blob: 61fc02d2b28c0c6acee75f172dc93a9b66e9a36b [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
20# include <ctype.h> /* tolower() */
21# include <descrip.h> /* string descriptors */
22# include <dvidef.h> /* DVI$_name */
23# include <file.h> /* -> O_RDWR */
24# include <jpidef.h> /* JPI$_name */
25# include <lib$routines.h> /* LIB$name */
26# include <ots$routines.h> /* OTS$name */
27# include <ssdef.h> /* SS$_name */
28# include <unixio.h>
29# include <unixlib.h>
30# include <stat.h>
31/* ----- */
32/* DECC on Alpha does redefine these already */
33# ifndef shell$from_vms
34# define shell$from_vms(_p1_,_p2_,_p3_) decc$from_vms(_p1_,_p2_,_p3_)
35# endif
36# ifndef shell$translate_vms
37# define shell$translate_vms(_p1_) decc$translate_vms(_p1_)
38# endif
39# ifndef shell$to_vms
40# define shell$to_vms(_p1_,_p2_,_p3_,_p4_,_p5_) \
41 decc$to_vms(_p1_,_p2_,_p3_,_p4_,_p5_)
42# endif
43# include <wait.h> /* define wait() */
44#endif /* defined(__VMS) */
45
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000047"This module provides access to operating system functionality that is\n\
48standardized by the C Standard and the POSIX standard (a thinly\n\
49disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000050corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000052#ifndef Py_USING_UNICODE
53/* This is used in signatures of functions. */
54#define Py_UNICODE void
55#endif
56
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#if defined(PYOS_OS2)
58#define INCL_DOS
59#define INCL_DOSERRORS
60#define INCL_DOSPROCESS
61#define INCL_NOPMAPI
62#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#if defined(PYCC_GCC)
64#include <ctype.h>
65#include <io.h>
66#include <stdio.h>
67#include <process.h>
68#include "osdefs.h"
69#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000070#endif
71
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/types.h>
73#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
76#include <sys/wait.h> /* For WNOHANG */
77#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#ifdef HAVE_SIGNAL_H
80#include <signal.h>
81#endif
82
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Guido van Rossuma4916fa1996-05-23 22:58:55 +000091/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000092/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000093#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000094#include <process.h>
95#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000096#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#define HAVE_GETCWD 1
98#define HAVE_OPENDIR 1
99#define HAVE_SYSTEM 1
100#if defined(__OS2__)
101#define HAVE_EXECV 1
102#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#include <process.h>
105#else
106#ifdef __BORLANDC__ /* Borland compiler */
107#define HAVE_EXECV 1
108#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#define HAVE_OPENDIR 1
110#define HAVE_PIPE 1
111#define HAVE_POPEN 1
112#define HAVE_SYSTEM 1
113#define HAVE_WAIT 1
114#else
115#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000116#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000117#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_EXECV 1
119#define HAVE_PIPE 1
120#define HAVE_POPEN 1
121#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000122#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000123#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000124#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
125/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#else /* all other compilers */
127/* Unix functions that the configure script doesn't check for */
128#define HAVE_EXECV 1
129#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000130#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
131#define HAVE_FORK1 1
132#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000133#define HAVE_GETCWD 1
134#define HAVE_GETEGID 1
135#define HAVE_GETEUID 1
136#define HAVE_GETGID 1
137#define HAVE_GETPPID 1
138#define HAVE_GETUID 1
139#define HAVE_KILL 1
140#define HAVE_OPENDIR 1
141#define HAVE_PIPE 1
142#define HAVE_POPEN 1
143#define HAVE_SYSTEM 1
144#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000145#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000146#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#endif /* _MSC_VER */
148#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000149#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000151
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000153
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000154#if defined(sun) && !defined(__SVR4)
155/* SunOS 4.1.4 doesn't have prototypes for these: */
156extern int rename(const char *, const char *);
157extern int pclose(FILE *);
158extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000159extern int fsync(int);
160extern int lstat(const char *, struct stat *);
161extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000162#endif
163
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000164#if defined(__sgi)&&_COMPILER_VERSION>=700
165/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
166 (default) */
167extern char *ctermid_r(char *);
168#endif
169
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000170#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000174#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000179#endif
180#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(char *);
182extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chdir(const char *);
185extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000186#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000187#ifdef __BORLANDC__
188extern int chmod(const char *, int);
189#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000190extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000191#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chown(const char *, uid_t, gid_t);
193extern char *getcwd(char *, int);
194extern char *strerror(int);
195extern int link(const char *, const char *);
196extern int rename(const char *, const char *);
197extern int stat(const char *, struct stat *);
198extern int unlink(const char *);
199extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000202#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000205#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000207
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#ifdef HAVE_UTIME_H
211#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000212#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000214#ifdef HAVE_SYS_UTIME_H
215#include <sys/utime.h>
216#define HAVE_UTIME_H /* pretend we do for the rest of this file */
217#endif /* HAVE_SYS_UTIME_H */
218
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#ifdef HAVE_SYS_TIMES_H
220#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
223#ifdef HAVE_SYS_PARAM_H
224#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
227#ifdef HAVE_SYS_UTSNAME_H
228#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000231#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#define NAMLEN(dirent) strlen((dirent)->d_name)
234#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000235#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#include <direct.h>
237#define NAMLEN(dirent) strlen((dirent)->d_name)
238#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000241#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#endif
245#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000247#endif
248#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#endif
251#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000253#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <direct.h>
255#include <io.h>
256#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000257#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000258#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000260#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000262#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000263#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
Guido van Rossumd48f2521997-12-05 22:19:34 +0000265#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000268
Tim Petersbc2e10e2002-03-03 23:17:02 +0000269#ifndef MAXPATHLEN
270#define MAXPATHLEN 1024
271#endif /* MAXPATHLEN */
272
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000273#ifdef UNION_WAIT
274/* Emulate some macros on systems that have a union instead of macros */
275
276#ifndef WIFEXITED
277#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
278#endif
279
280#ifndef WEXITSTATUS
281#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
282#endif
283
284#ifndef WTERMSIG
285#define WTERMSIG(u_wait) ((u_wait).w_termsig)
286#endif
287
288#endif /* UNION_WAIT */
289
Greg Wardb48bc172000-03-01 21:51:56 +0000290/* Don't use the "_r" form if we don't need it (also, won't have a
291 prototype for it, at least on Solaris -- maybe others as well?). */
292#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
293#define USE_CTERMID_R
294#endif
295
296#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
297#define USE_TMPNAM_R
298#endif
299
Fred Drake699f3522000-06-29 21:12:41 +0000300/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000301#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000302#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000303# define STAT _stati64
304# define FSTAT _fstati64
305# define STRUCT_STAT struct _stati64
306#else
307# define STAT stat
308# define FSTAT fstat
309# define STRUCT_STAT struct stat
310#endif
311
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000312#if defined(MAJOR_IN_MKDEV)
313#include <sys/mkdev.h>
314#else
315#if defined(MAJOR_IN_SYSMACROS)
316#include <sys/sysmacros.h>
317#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000318#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
319#include <sys/mkdev.h>
320#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000321#endif
Fred Drake699f3522000-06-29 21:12:41 +0000322
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000324#ifdef WITH_NEXT_FRAMEWORK
325/* On Darwin/MacOSX a shared library or framework has no access to
326** environ directly, we must obtain it with _NSGetEnviron().
327*/
328#include <crt_externs.h>
329static char **environ;
330#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000332#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000334#if defined(__VMS)
335static char psxmod_gt_psxpath[1026];
336
337static int
338psxmod_from_vms_action (char *spec)
339{
340 (void)strcpy(psxmod_gt_psxpath, spec);
341 return 1;
342}
343
344/* Return a dictionary corresponding to the VMS 'environment table' */
345static char* at_home = "HOME";
346static char* at_path = "PATH";
347
348static char psxmod_t_command [] = "SYS$COMMAND";
349/* add some values to provide a similar environment like POSIX */
350void
351psmmod_add_posix_env(PyObject *d)
352{
353 /* -------------------- */
354 struct dsc$descriptor_s r_device_name;
355 long l_devbufsiz;
356 long l_tt_page;
357 long l_item_code;
358 long l_status;
359 PyObject *o;
360 struct dsc$descriptor_s r_resultant_string;
361 char t_resultant_string[13]; /* enough space for username (12)+ '\0' */
362 char *at_resultant_string;
363 short int w_resultant_length;
364
365 /* set up string descriptor */
366 r_device_name.dsc$w_length = strlen(psxmod_t_command);
367 r_device_name.dsc$b_dtype = DSC$K_DTYPE_T;
368 r_device_name.dsc$b_class = DSC$K_CLASS_S;
369 r_device_name.dsc$a_pointer = &psxmod_t_command[0];
370
371 /* -------------------- */
372 /* COLUMNS = $getdvi("SYS$COMMAND","DEVBUFSIZ") */
373 l_item_code = DVI$_DEVBUFSIZ;
374 l_status = lib$getdvi(&l_item_code,
375 0, /* [channel] */
376 &r_device_name,
377 &l_devbufsiz, /* integer-value */
378 0, /* resultant_string */
379 0); /* resultant_length */
380 if (l_status == SS$_NORMAL) {
381 /* create a string object here to comply with POSIX */
382
383 /* set up string descriptor */
384 r_resultant_string.dsc$w_length =
385 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
386 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
387 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
388 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
389
390 /* Convert Signed Integer to Decimal Text */
391 l_status = ots$cvt_l_ti(&l_devbufsiz, &r_resultant_string, 1,
392 4, 0);
393 if (l_status == SS$_NORMAL) {
394 /* terminate string for 'C'-style */
395 t_resultant_string[sizeof(t_resultant_string)-1] = '\0';
396 /* string appears as: ' value' -- skip ' ' */
397 at_resultant_string = &t_resultant_string[0];
398 while ((*at_resultant_string == ' ' ) &&
399 (*at_resultant_string != '\0')) {
400 at_resultant_string++; /* skip prefix spaces */
401 }
402
403 o = Py_BuildValue("s", at_resultant_string);
404 if (o != NULL) {
405 (void) PyDict_SetItemString(d, "COLUMNS", o);
406 Py_DECREF(o);
407 }
408 } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */
409 } /* (l_status = lib$getdvi(DVI$_DEVBUFSIZ) == SS$_NORMAL) */
410 /* LINES = $getdvi("SYS$COMMAND","TT_PAGE") */
411 l_item_code = DVI$_TT_PAGE;
412 l_status = lib$getdvi(&l_item_code,
413 0, /* [channel] */
414 &r_device_name,
415 &l_tt_page, /* integer-value */
416 0, /* resultant_string */
417 0); /* resultant_length */
418 if (l_status == SS$_NORMAL) {
419 /* create a string object here to comply with POSIX */
420
421 /* set up string descriptor */
422 r_resultant_string.dsc$w_length =
423 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
424 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
425 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
426 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
427
428 /* Convert Signed Integer to Decimal Text */
429 l_status = ots$cvt_l_ti(&l_tt_page, &r_resultant_string,
430 1, 4, 0);
431 if (l_status == SS$_NORMAL) {
432 /* terminate string for 'C'-style */
433 t_resultant_string[sizeof(t_resultant_string)-1] = '\0';
434 /* string appears as: ' value' -- skip ' ' */
435 at_resultant_string = &t_resultant_string[0];
436 while ((*at_resultant_string == ' ' ) &&
437 (*at_resultant_string != '\0')) {
438 at_resultant_string++; /* skip prefix spaces */
439 }
440
441 o = Py_BuildValue("s", at_resultant_string);
442 if (o != NULL) {
443 (void)PyDict_SetItemString(d, "LINES", o);
444 Py_DECREF(o);
445 }
446 } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */
447 } /* (l_status = lib$getdvi(DVI$_TT_PAGE) == SS$_NORMAL) */
448 /* else -- ignore error */
449
450 /* LOGNAME = $getjpi(0,"USERNAME") */
451 l_item_code = JPI$_USERNAME;
452
453 /* set up string descriptor */
454 r_resultant_string.dsc$w_length =
455 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
456 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
457 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
458 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
459
460 l_status = lib$getjpi(&l_item_code, 0, 0, 0,
461 &r_resultant_string, &w_resultant_length);
462 if (l_status == SS$_NORMAL){
463 t_resultant_string[w_resultant_length] = '\0';
464
465 /* remove any trailing spaces by replacing 1st one with '\0' */
466 at_resultant_string = &t_resultant_string[0];
467 while ((*at_resultant_string != ' ' ) &&
468 (*at_resultant_string != '\0')) {
469 /* lowercase for compatibility with POSIX */
470 *at_resultant_string = tolower(*at_resultant_string);
471 at_resultant_string++; /* skip non-blank */
472 }
473 *at_resultant_string = '\0'; /* terminate */
474
475 o = Py_BuildValue("s", &t_resultant_string[0]);
476 if (o != NULL) {
477 (void) PyDict_SetItemString(d, "LOGNAME", o);
478 (void) PyDict_SetItemString(d, "USERNAME", o);
479 Py_DECREF(o);
480 }
481 } /* (l_status == SS$_NORMAL) */
482
483 /* OS = "OpenVMS" */
484 o = PyString_FromString ("OpenVMS");
485 if (o != NULL) {
486 (void)PyDict_SetItemString(d, "OS", o);
487 Py_DECREF(o);
488 }
489}
490
491/* @@ posix env:
492COLUMNS=80 $ write sys$output f$getdvi("SYS$COMMAND","DEVBUFSIZ")
493LINES=47 $ write sys$output f$getdvi("SYS$COMMAND","TT_PAGE")
494LOGNAME=zessin $ write sys$output f$edit(f$getjpi(0,"username"), -
495 "collapse,lowercase")
496OS=OpenVMS
497PS1=HERE $
498
499TZ=CET-1:00CET DST,M3.5.0/2:00,M10.5.0/3:00
500 $ write sys$output f$trnlnm("POSIX$DEFAULT_TZ")
501 "CET-1:00CET DST-2:00,M3.5.0/2:00,M10.5.0/3:00"
502 $ write sys$output f$trnlnm("UCX$TZ")
503 "MET-1MET_DST-2,M3.5.0/2,M10.5.0/3"
504PAGER=more
505TERM=vt300_series
506SHELL=/bin/sh
507HOME=/dka100/user/zessin
508_=/bin/env
509
510>>> for v in os.environ.items():
511... print v
512...
513('HOME', '/user_here/zessin')
514('COLUMNS', '80')
515('LINES', '24')
516('PATH', '/python_disk/python/python-1_5_2/vms')
517('OS', 'OpenVMS')
518('USER', 'ZESSIN')
519('LOGNAME', 'zessin')
520('TERM', 'vt300-80')
521('USERNAME', 'zessin')
522>>>
523*/
524#endif /* __VMS */
525
Barry Warsaw53699e91996-12-10 23:23:01 +0000526static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000527convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528{
Barry Warsaw53699e91996-12-10 23:23:01 +0000529 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000530 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000531 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532 if (d == NULL)
533 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000534#ifdef WITH_NEXT_FRAMEWORK
535 if (environ == NULL)
536 environ = *_NSGetEnviron();
537#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 if (environ == NULL)
539 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000540 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000542 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000543 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544 char *p = strchr(*e, '=');
545 if (p == NULL)
546 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000547 k = PyString_FromStringAndSize(*e, (int)(p-*e));
548 if (k == NULL) {
549 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000551 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000552#if defined(__VMS)
553 if ((strncmp(at_home, *e, sizeof(at_home)) == 0) ||
554 (strncmp(at_path, *e, sizeof(at_path)) == 0)) {
555 (void)shell$from_vms(p+1, psxmod_from_vms_action, 0);
556 /* 0 = no wildcard expansion */
557 v = PyString_FromString(psxmod_gt_psxpath);
558 }
559 else {
560 v = PyString_FromString(p+1);
561 }
562#else
Guido van Rossum6a619f41999-08-03 19:41:10 +0000563 v = PyString_FromString(p+1);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000564#endif
Guido van Rossum6a619f41999-08-03 19:41:10 +0000565 if (v == NULL) {
566 PyErr_Clear();
567 Py_DECREF(k);
568 continue;
569 }
570 if (PyDict_GetItem(d, k) == NULL) {
571 if (PyDict_SetItem(d, k, v) != 0)
572 PyErr_Clear();
573 }
574 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000575 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000577#if defined(__VMS)
578 psmmod_add_posix_env(d);
579#endif /* defined(__VMS) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000580#if defined(PYOS_OS2)
581 {
582 APIRET rc;
583 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
584
585 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000586 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000587 PyObject *v = PyString_FromString(buffer);
588 PyDict_SetItemString(d, "BEGINLIBPATH", v);
589 Py_DECREF(v);
590 }
591 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
592 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
593 PyObject *v = PyString_FromString(buffer);
594 PyDict_SetItemString(d, "ENDLIBPATH", v);
595 Py_DECREF(v);
596 }
597 }
598#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000599 return d;
600}
601
602
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603/* Set a POSIX-specific error from errno, and return NULL */
604
Barry Warsawd58d7641998-07-23 16:14:40 +0000605static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000606posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000607{
Barry Warsawca74da41999-02-09 19:31:45 +0000608 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609}
Barry Warsawd58d7641998-07-23 16:14:40 +0000610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000611posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000612{
Barry Warsawca74da41999-02-09 19:31:45 +0000613 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000614}
615
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616#ifdef Py_WIN_WIDE_FILENAMES
617static PyObject *
618posix_error_with_unicode_filename(Py_UNICODE* name)
619{
620 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
621}
622#endif /* Py_WIN_WIDE_FILENAMES */
623
624
Mark Hammondef8b6542001-05-13 08:04:26 +0000625static PyObject *
626posix_error_with_allocated_filename(char* name)
627{
628 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
629 PyMem_Free(name);
630 return rc;
631}
632
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000633#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000634static PyObject *
635win32_error(char* function, char* filename)
636{
Mark Hammond33a6da92000-08-15 00:46:38 +0000637 /* XXX We should pass the function name along in the future.
638 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000639 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000640 Windows error object, which is non-trivial.
641 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000642 errno = GetLastError();
643 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000644 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000645 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000646 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000647}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000648
649#ifdef Py_WIN_WIDE_FILENAMES
650static PyObject *
651win32_error_unicode(char* function, Py_UNICODE* filename)
652{
653 /* XXX - see win32_error for comments on 'function' */
654 errno = GetLastError();
655 if (filename)
656 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
657 else
658 return PyErr_SetFromWindowsErr(errno);
659}
660
661static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
662{
663 /* XXX Perhaps we should make this API an alias of
664 PyObject_Unicode() instead ?! */
665 if (PyUnicode_CheckExact(obj)) {
666 Py_INCREF(obj);
667 return obj;
668 }
669 if (PyUnicode_Check(obj)) {
670 /* For a Unicode subtype that's not a Unicode object,
671 return a true Unicode object with the same data. */
672 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
673 PyUnicode_GET_SIZE(obj));
674 }
675 return PyUnicode_FromEncodedObject(obj,
676 Py_FileSystemDefaultEncoding,
677 "strict");
678}
679
680#endif /* Py_WIN_WIDE_FILENAMES */
681
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000682#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683
Guido van Rossumd48f2521997-12-05 22:19:34 +0000684#if defined(PYOS_OS2)
685/**********************************************************************
686 * Helper Function to Trim and Format OS/2 Messages
687 **********************************************************************/
688 static void
689os2_formatmsg(char *msgbuf, int msglen, char *reason)
690{
691 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
692
693 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
694 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
695
696 while (lastc > msgbuf && isspace(*lastc))
697 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
698 }
699
700 /* Add Optional Reason Text */
701 if (reason) {
702 strcat(msgbuf, " : ");
703 strcat(msgbuf, reason);
704 }
705}
706
707/**********************************************************************
708 * Decode an OS/2 Operating System Error Code
709 *
710 * A convenience function to lookup an OS/2 error code and return a
711 * text message we can use to raise a Python exception.
712 *
713 * Notes:
714 * The messages for errors returned from the OS/2 kernel reside in
715 * the file OSO001.MSG in the \OS2 directory hierarchy.
716 *
717 **********************************************************************/
718 static char *
719os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
720{
721 APIRET rc;
722 ULONG msglen;
723
724 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
725 Py_BEGIN_ALLOW_THREADS
726 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
727 errorcode, "oso001.msg", &msglen);
728 Py_END_ALLOW_THREADS
729
730 if (rc == NO_ERROR)
731 os2_formatmsg(msgbuf, msglen, reason);
732 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000733 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000734 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000735
736 return msgbuf;
737}
738
739/* Set an OS/2-specific error and return NULL. OS/2 kernel
740 errors are not in a global variable e.g. 'errno' nor are
741 they congruent with posix error numbers. */
742
743static PyObject * os2_error(int code)
744{
745 char text[1024];
746 PyObject *v;
747
748 os2_strerror(text, sizeof(text), code, "");
749
750 v = Py_BuildValue("(is)", code, text);
751 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000752 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000753 Py_DECREF(v);
754 }
755 return NULL; /* Signal to Python that an Exception is Pending */
756}
757
758#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000759
760/* POSIX generic methods */
761
Barry Warsaw53699e91996-12-10 23:23:01 +0000762static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000763posix_fildes(PyObject *fdobj, int (*func)(int))
764{
765 int fd;
766 int res;
767 fd = PyObject_AsFileDescriptor(fdobj);
768 if (fd < 0)
769 return NULL;
770 Py_BEGIN_ALLOW_THREADS
771 res = (*func)(fd);
772 Py_END_ALLOW_THREADS
773 if (res < 0)
774 return posix_error();
775 Py_INCREF(Py_None);
776 return Py_None;
777}
Guido van Rossum21142a01999-01-08 21:05:37 +0000778
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000779#ifdef Py_WIN_WIDE_FILENAMES
780static int
781unicode_file_names(void)
782{
783 static int canusewide = -1;
784 if (canusewide == -1) {
785 /* As per doc for ::GetVersion(), this is the correct test for
786 the Windows NT family. */
787 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
788 }
789 return canusewide;
790}
791#endif
792
Guido van Rossum21142a01999-01-08 21:05:37 +0000793static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000794posix_1str(PyObject *args, char *format, int (*func)(const char*),
795 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796{
Mark Hammondef8b6542001-05-13 08:04:26 +0000797 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000798 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000799#ifdef Py_WIN_WIDE_FILENAMES
800 if (unicode_file_names()) {
801 PyUnicodeObject *po;
802 if (PyArg_ParseTuple(args, wformat, &po)) {
803 Py_BEGIN_ALLOW_THREADS
804 /* PyUnicode_AS_UNICODE OK without thread
805 lock as it is a simple dereference. */
806 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
807 Py_END_ALLOW_THREADS
808 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000809 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000810 Py_INCREF(Py_None);
811 return Py_None;
812 }
813 /* Drop the argument parsing error as narrow
814 strings are also valid. */
815 PyErr_Clear();
816 }
817#else
818 /* Platforms that don't support Unicode filenames
819 shouldn't be passing these extra params */
820 assert(wformat==NULL && wfunc == NULL);
821#endif
822
Tim Peters5aa91602002-01-30 05:46:57 +0000823 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000824 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000826 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000827 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000828 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000829 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000830 return posix_error_with_allocated_filename(path1);
831 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000832 Py_INCREF(Py_None);
833 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000834}
835
Barry Warsaw53699e91996-12-10 23:23:01 +0000836static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000837posix_2str(PyObject *args,
838 char *format,
839 int (*func)(const char *, const char *),
840 char *wformat,
841 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000842{
Mark Hammondef8b6542001-05-13 08:04:26 +0000843 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000844 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000845#ifdef Py_WIN_WIDE_FILENAMES
846 if (unicode_file_names()) {
847 PyObject *po1;
848 PyObject *po2;
849 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
850 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
851 PyObject *wpath1;
852 PyObject *wpath2;
853 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
854 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
855 if (!wpath1 || !wpath2) {
856 Py_XDECREF(wpath1);
857 Py_XDECREF(wpath2);
858 return NULL;
859 }
860 Py_BEGIN_ALLOW_THREADS
861 /* PyUnicode_AS_UNICODE OK without thread
862 lock as it is a simple dereference. */
863 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
864 PyUnicode_AS_UNICODE(wpath2));
865 Py_END_ALLOW_THREADS
866 Py_XDECREF(wpath1);
867 Py_XDECREF(wpath2);
868 if (res != 0)
869 return posix_error();
870 Py_INCREF(Py_None);
871 return Py_None;
872 }
873 /* Else flow through as neither is Unicode. */
874 }
875 /* Drop the argument parsing error as narrow
876 strings are also valid. */
877 PyErr_Clear();
878 }
879#else
880 /* Platforms that don't support Unicode filenames
881 shouldn't be passing these extra params */
882 assert(wformat==NULL && wfunc == NULL);
883#endif
884
Mark Hammondef8b6542001-05-13 08:04:26 +0000885 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000886 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000887 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000889 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000890 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000891 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000892 PyMem_Free(path1);
893 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000894 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000895 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000896 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000897 Py_INCREF(Py_None);
898 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000899}
900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000901PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000902"stat_result: Result from stat or lstat.\n\n\
903This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000904 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000905or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
906\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000907Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000908they are available as attributes only.\n\
909\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000910See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000911
912static PyStructSequence_Field stat_result_fields[] = {
913 {"st_mode", "protection bits"},
914 {"st_ino", "inode"},
915 {"st_dev", "device"},
916 {"st_nlink", "number of hard links"},
917 {"st_uid", "user ID of owner"},
918 {"st_gid", "group ID of owner"},
919 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000920 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
921 {NULL, "integer time of last access"},
922 {NULL, "integer time of last modification"},
923 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000924 {"st_atime", "time of last access"},
925 {"st_mtime", "time of last modification"},
926 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000927#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000928 {"st_blksize", "blocksize for filesystem I/O"},
929#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000930#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931 {"st_blocks", "number of blocks allocated"},
932#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000933#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000934 {"st_rdev", "device type (if inode device)"},
935#endif
936 {0}
937};
938
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000939#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000940#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000941#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000942#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000943#endif
944
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000945#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000946#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
947#else
948#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
949#endif
950
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000951#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000952#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
953#else
954#define ST_RDEV_IDX ST_BLOCKS_IDX
955#endif
956
957static PyStructSequence_Desc stat_result_desc = {
958 "stat_result", /* name */
959 stat_result__doc__, /* doc */
960 stat_result_fields,
961 10
962};
963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000964PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000965"statvfs_result: Result from statvfs or fstatvfs.\n\n\
966This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000967 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000968or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000969\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000970See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000971
972static PyStructSequence_Field statvfs_result_fields[] = {
973 {"f_bsize", },
974 {"f_frsize", },
975 {"f_blocks", },
976 {"f_bfree", },
977 {"f_bavail", },
978 {"f_files", },
979 {"f_ffree", },
980 {"f_favail", },
981 {"f_flag", },
982 {"f_namemax",},
983 {0}
984};
985
986static PyStructSequence_Desc statvfs_result_desc = {
987 "statvfs_result", /* name */
988 statvfs_result__doc__, /* doc */
989 statvfs_result_fields,
990 10
991};
992
993static PyTypeObject StatResultType;
994static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000995static newfunc structseq_new;
996
997static PyObject *
998statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
999{
1000 PyStructSequence *result;
1001 int i;
1002
1003 result = (PyStructSequence*)structseq_new(type, args, kwds);
1004 if (!result)
1005 return NULL;
1006 /* If we have been initialized from a tuple,
1007 st_?time might be set to None. Initialize it
1008 from the int slots. */
1009 for (i = 7; i <= 9; i++) {
1010 if (result->ob_item[i+3] == Py_None) {
1011 Py_DECREF(Py_None);
1012 Py_INCREF(result->ob_item[i]);
1013 result->ob_item[i+3] = result->ob_item[i];
1014 }
1015 }
1016 return (PyObject*)result;
1017}
1018
1019
1020
1021/* If true, st_?time is float. */
1022static int _stat_float_times = 0;
1023
1024PyDoc_STRVAR(stat_float_times__doc__,
1025"stat_float_times([newval]) -> oldval\n\n\
1026Determine whether os.[lf]stat represents time stamps as float objects.\n\
1027If newval is True, future calls to stat() return floats, if it is False,\n\
1028future calls return ints. \n\
1029If newval is omitted, return the current setting.\n");
1030
1031static PyObject*
1032stat_float_times(PyObject* self, PyObject *args)
1033{
1034 int newval = -1;
1035 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1036 return NULL;
1037 if (newval == -1)
1038 /* Return old value */
1039 return PyBool_FromLong(_stat_float_times);
1040 _stat_float_times = newval;
1041 Py_INCREF(Py_None);
1042 return Py_None;
1043}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001044
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001045static void
1046fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1047{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001048 PyObject *fval,*ival;
1049#if SIZEOF_TIME_T > SIZEOF_LONG
1050 ival = PyLong_FromLongLong((LONG_LONG)sec);
1051#else
1052 ival = PyInt_FromLong((long)sec);
1053#endif
1054 if (_stat_float_times) {
1055 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1056 } else {
1057 fval = ival;
1058 Py_INCREF(fval);
1059 }
1060 PyStructSequence_SET_ITEM(v, index, ival);
1061 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001062}
1063
Tim Peters5aa91602002-01-30 05:46:57 +00001064/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001065 (used by posix_stat() and posix_fstat()) */
1066static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001067_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +00001068{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001069 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001070 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001071 if (v == NULL)
1072 return NULL;
1073
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001074 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001075#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001076 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001077 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001078#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001079 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001080#endif
1081#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001082 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001084#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001085 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001086#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001087 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
1088 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
1089 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001090#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001091 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001092 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001093#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001094 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001095#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001096
1097#ifdef HAVE_STAT_TV_NSEC
1098 ansec = st.st_atim.tv_nsec;
1099 mnsec = st.st_mtim.tv_nsec;
1100 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +00001101#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001102 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001104 fill_time(v, 7, st.st_atime, ansec);
1105 fill_time(v, 8, st.st_mtime, mnsec);
1106 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001108#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001109 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001110 PyInt_FromLong((long)st.st_blksize));
1111#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001112#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001113 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114 PyInt_FromLong((long)st.st_blocks));
1115#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001116#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001117 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1118 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001119#endif
1120
1121 if (PyErr_Occurred()) {
1122 Py_DECREF(v);
1123 return NULL;
1124 }
1125
1126 return v;
1127}
1128
Barry Warsaw53699e91996-12-10 23:23:01 +00001129static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001130posix_do_stat(PyObject *self, PyObject *args,
1131 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001132#ifdef __VMS
1133 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1134#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001135 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001136#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001137 char *wformat,
1138 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139{
Fred Drake699f3522000-06-29 21:12:41 +00001140 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001141 char *path = NULL; /* pass this to stat; do not free() it */
1142 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001143 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001144
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001145#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +00001146 int pathlen;
1147 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001148#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001149
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001150
1151#ifdef Py_WIN_WIDE_FILENAMES
1152 /* If on wide-character-capable OS see if argument
1153 is Unicode and if so use wide API. */
1154 if (unicode_file_names()) {
1155 PyUnicodeObject *po;
1156 if (PyArg_ParseTuple(args, wformat, &po)) {
1157 Py_UNICODE wpath[MAX_PATH+1];
1158 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1159 /* the library call can blow up if the file name is too long! */
1160 if (pathlen > MAX_PATH) {
1161 errno = ENAMETOOLONG;
1162 return posix_error();
1163 }
1164 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1165 /* Remove trailing slash or backslash, unless it's the current
1166 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1167 */
1168 if (pathlen > 0 &&
1169 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1170 /* It does end with a slash -- exempt the root drive cases. */
1171 /* XXX UNC root drives should also be exempted? */
1172 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1173 /* leave it alone */;
1174 else {
1175 /* nuke the trailing backslash */
1176 wpath[pathlen-1] = L'\0';
1177 }
1178 }
1179 Py_BEGIN_ALLOW_THREADS
1180 /* PyUnicode_AS_UNICODE result OK without
1181 thread lock as it is a simple dereference. */
1182 res = wstatfunc(wpath, &st);
1183 Py_END_ALLOW_THREADS
1184 if (res != 0)
1185 return posix_error_with_unicode_filename(wpath);
1186 return _pystat_fromstructstat(st);
1187 }
1188 /* Drop the argument parsing error as narrow strings
1189 are also valid. */
1190 PyErr_Clear();
1191 }
1192#endif
1193
Tim Peters5aa91602002-01-30 05:46:57 +00001194 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001195 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001196 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001197 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001198
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001199#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001200 pathlen = strlen(path);
1201 /* the library call can blow up if the file name is too long! */
1202 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001203 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001204 errno = ENAMETOOLONG;
1205 return posix_error();
1206 }
1207
Tim Peters500bd032001-12-19 19:05:01 +00001208 /* Remove trailing slash or backslash, unless it's the current
1209 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1210 */
1211 if (pathlen > 0 &&
1212 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1213 /* It does end with a slash -- exempt the root drive cases. */
1214 /* XXX UNC root drives should also be exempted? */
1215 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1216 /* leave it alone */;
1217 else {
1218 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001219 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001220 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001221 path = pathcopy;
1222 }
1223 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001224#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001225
Barry Warsaw53699e91996-12-10 23:23:01 +00001226 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001227 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001228 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001229 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001230 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001231
Tim Peters500bd032001-12-19 19:05:01 +00001232 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001233 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234}
1235
1236
1237/* POSIX methods */
1238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001239PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001240"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001241Use the real uid/gid to test for access to a path. Note that most\n\
1242operations will use the effective uid/gid, therefore this routine can\n\
1243be used in a suid/sgid environment to test if the invoking user has the\n\
1244specified access to the path. The mode argument can be F_OK to test\n\
1245existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001246
1247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001248posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001249{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001250 char *path;
1251 int mode;
1252 int res;
1253
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001254 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001255 return NULL;
1256 Py_BEGIN_ALLOW_THREADS
1257 res = access(path, mode);
1258 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001259 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001260}
1261
Guido van Rossumd371ff11999-01-25 16:12:23 +00001262#ifndef F_OK
1263#define F_OK 0
1264#endif
1265#ifndef R_OK
1266#define R_OK 4
1267#endif
1268#ifndef W_OK
1269#define W_OK 2
1270#endif
1271#ifndef X_OK
1272#define X_OK 1
1273#endif
1274
1275#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001276PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001277"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001278Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001279
1280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001282{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001283 int id;
1284 char *ret;
1285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001286 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001287 return NULL;
1288
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001289#if defined(__VMS)
1290 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1291 if (id == 0) {
1292 ret = ttyname();
1293 }
1294 else {
1295 ret = NULL;
1296 }
1297#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001298 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001299#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001300 if (ret == NULL)
1301 return(posix_error());
1302 return(PyString_FromString(ret));
1303}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001304#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001305
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001306#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001307PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001308"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001309Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001310
1311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001312posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001313{
1314 char *ret;
1315 char buffer[L_ctermid];
1316
1317 if (!PyArg_ParseTuple(args, ":ctermid"))
1318 return NULL;
1319
Greg Wardb48bc172000-03-01 21:51:56 +00001320#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001321 ret = ctermid_r(buffer);
1322#else
1323 ret = ctermid(buffer);
1324#endif
1325 if (ret == NULL)
1326 return(posix_error());
1327 return(PyString_FromString(buffer));
1328}
1329#endif
1330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001331PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001332"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001333Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001334
Barry Warsaw53699e91996-12-10 23:23:01 +00001335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001336posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001338#ifdef MS_WINDOWS
1339 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1340#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1341 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001342#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001343#ifdef __VMS
1344 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1345 NULL, NULL);
1346#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001347 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001348#endif
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001349#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
1351
Fred Drake4d1e64b2002-04-15 19:40:07 +00001352#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001353PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001354"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001355Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001356opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001357
1358static PyObject *
1359posix_fchdir(PyObject *self, PyObject *fdobj)
1360{
1361 return posix_fildes(fdobj, fchdir);
1362}
1363#endif /* HAVE_FCHDIR */
1364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001366PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001367"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001368Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372{
Mark Hammondef8b6542001-05-13 08:04:26 +00001373 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001374 int i;
1375 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001376 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001377 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001378 return NULL;
1379 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001380 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001381 Py_END_ALLOW_THREADS
1382 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001383 return posix_error_with_allocated_filename(path);
1384 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001385 Py_INCREF(Py_None);
1386 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001387}
1388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001389
Martin v. Löwis244edc82001-10-04 22:44:26 +00001390#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001391PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001392"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001393Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001394
1395static PyObject *
1396posix_chroot(PyObject *self, PyObject *args)
1397{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001398 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001399}
1400#endif
1401
Guido van Rossum21142a01999-01-08 21:05:37 +00001402#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001403PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001404"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001405force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001406
1407static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001408posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001409{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001410 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001411}
1412#endif /* HAVE_FSYNC */
1413
1414#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001415
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001416#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001417extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1418#endif
1419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001421"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001422force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001423 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001424
1425static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001426posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001427{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001428 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001429}
1430#endif /* HAVE_FDATASYNC */
1431
1432
Fredrik Lundh10723342000-07-10 16:38:09 +00001433#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001435"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001436Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001437
Barry Warsaw53699e91996-12-10 23:23:01 +00001438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001439posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001440{
Mark Hammondef8b6542001-05-13 08:04:26 +00001441 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001442 int uid, gid;
1443 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001444 if (!PyArg_ParseTuple(args, "etii:chown",
1445 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001446 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001447 return NULL;
1448 Py_BEGIN_ALLOW_THREADS
1449 res = chown(path, (uid_t) uid, (gid_t) gid);
1450 Py_END_ALLOW_THREADS
1451 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001452 return posix_error_with_allocated_filename(path);
1453 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001454 Py_INCREF(Py_None);
1455 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001456}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001457#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001458
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001459#ifdef HAVE_LCHOWN
1460PyDoc_STRVAR(posix_lchown__doc__,
1461"lchown(path, uid, gid)\n\n\
1462Change the owner and group id of path to the numeric uid and gid.\n\
1463This function will not follow symbolic links.");
1464
1465static PyObject *
1466posix_lchown(PyObject *self, PyObject *args)
1467{
1468 char *path = NULL;
1469 int uid, gid;
1470 int res;
1471 if (!PyArg_ParseTuple(args, "etii:lchown",
1472 Py_FileSystemDefaultEncoding, &path,
1473 &uid, &gid))
1474 return NULL;
1475 Py_BEGIN_ALLOW_THREADS
1476 res = lchown(path, (uid_t) uid, (gid_t) gid);
1477 Py_END_ALLOW_THREADS
1478 if (res < 0)
1479 return posix_error_with_allocated_filename(path);
1480 PyMem_Free(path);
1481 Py_INCREF(Py_None);
1482 return Py_None;
1483}
1484#endif /* HAVE_LCHOWN */
1485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001486
Guido van Rossum36bc6801995-06-14 22:54:23 +00001487#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001488PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001489"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001490Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001491
Barry Warsaw53699e91996-12-10 23:23:01 +00001492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001493posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001494{
1495 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001496 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001497 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001499 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001500#if defined(PYOS_OS2) && defined(PYCC_GCC)
1501 res = _getcwd2(buf, sizeof buf);
1502#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001503#if defined(__VMS)
1504 /* 0 = force Unix-style path if in the VMS DCL environment! */
1505 res = getcwd(buf, sizeof buf, 0);
1506#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001507 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001508#endif
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001509#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001510 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001511 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001512 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001514}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001515
Walter Dörwald3b918c32002-11-21 20:18:46 +00001516#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001517PyDoc_STRVAR(posix_getcwdu__doc__,
1518"getcwdu() -> path\n\n\
1519Return a unicode string representing the current working directory.");
1520
1521static PyObject *
1522posix_getcwdu(PyObject *self, PyObject *args)
1523{
1524 char buf[1026];
1525 char *res;
1526 if (!PyArg_ParseTuple(args, ":getcwd"))
1527 return NULL;
1528
1529#ifdef Py_WIN_WIDE_FILENAMES
1530 if (unicode_file_names()) {
1531 wchar_t *wres;
1532 wchar_t wbuf[1026];
1533 Py_BEGIN_ALLOW_THREADS
1534 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1535 Py_END_ALLOW_THREADS
1536 if (wres == NULL)
1537 return posix_error();
1538 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1539 }
1540#endif
1541
1542 Py_BEGIN_ALLOW_THREADS
1543#if defined(PYOS_OS2) && defined(PYCC_GCC)
1544 res = _getcwd2(buf, sizeof buf);
1545#else
1546 res = getcwd(buf, sizeof buf);
1547#endif
1548 Py_END_ALLOW_THREADS
1549 if (res == NULL)
1550 return posix_error();
1551 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1552}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001553#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001554#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001556
Guido van Rossumb6775db1994-08-01 11:34:53 +00001557#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001558PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001559"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001560Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001561
Barry Warsaw53699e91996-12-10 23:23:01 +00001562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001563posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001564{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001565 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001566}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001567#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001568
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001570PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001571"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001572Return a list containing the names of the entries in the directory.\n\
1573\n\
1574 path: path of directory to list\n\
1575\n\
1576The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001577entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001578
Barry Warsaw53699e91996-12-10 23:23:01 +00001579static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001580posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001581{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001582 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001583 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001584#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001585
Barry Warsaw53699e91996-12-10 23:23:01 +00001586 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001587 HANDLE hFindFile;
1588 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001589 /* MAX_PATH characters could mean a bigger encoded string */
1590 char namebuf[MAX_PATH*2+5];
1591 char *bufptr = namebuf;
1592 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001593
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001594#ifdef Py_WIN_WIDE_FILENAMES
1595 /* If on wide-character-capable OS see if argument
1596 is Unicode and if so use wide API. */
1597 if (unicode_file_names()) {
1598 PyUnicodeObject *po;
1599 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1600 WIN32_FIND_DATAW wFileData;
1601 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1602 Py_UNICODE wch;
1603 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1604 wnamebuf[MAX_PATH] = L'\0';
1605 len = wcslen(wnamebuf);
1606 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1607 if (wch != L'/' && wch != L'\\' && wch != L':')
1608 wnamebuf[len++] = L'/';
1609 wcscpy(wnamebuf + len, L"*.*");
1610 if ((d = PyList_New(0)) == NULL)
1611 return NULL;
1612 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1613 if (hFindFile == INVALID_HANDLE_VALUE) {
1614 errno = GetLastError();
1615 if (errno == ERROR_FILE_NOT_FOUND) {
1616 return d;
1617 }
1618 Py_DECREF(d);
1619 return win32_error_unicode("FindFirstFileW", wnamebuf);
1620 }
1621 do {
1622 if (wFileData.cFileName[0] == L'.' &&
1623 (wFileData.cFileName[1] == L'\0' ||
1624 wFileData.cFileName[1] == L'.' &&
1625 wFileData.cFileName[2] == L'\0'))
1626 continue;
1627 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1628 if (v == NULL) {
1629 Py_DECREF(d);
1630 d = NULL;
1631 break;
1632 }
1633 if (PyList_Append(d, v) != 0) {
1634 Py_DECREF(v);
1635 Py_DECREF(d);
1636 d = NULL;
1637 break;
1638 }
1639 Py_DECREF(v);
1640 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1641
1642 if (FindClose(hFindFile) == FALSE) {
1643 Py_DECREF(d);
1644 return win32_error_unicode("FindClose", wnamebuf);
1645 }
1646 return d;
1647 }
1648 /* Drop the argument parsing error as narrow strings
1649 are also valid. */
1650 PyErr_Clear();
1651 }
1652#endif
1653
Tim Peters5aa91602002-01-30 05:46:57 +00001654 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001655 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001656 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001657 if (len > 0) {
1658 char ch = namebuf[len-1];
1659 if (ch != SEP && ch != ALTSEP && ch != ':')
1660 namebuf[len++] = '/';
1661 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001662 strcpy(namebuf + len, "*.*");
1663
Barry Warsaw53699e91996-12-10 23:23:01 +00001664 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001665 return NULL;
1666
1667 hFindFile = FindFirstFile(namebuf, &FileData);
1668 if (hFindFile == INVALID_HANDLE_VALUE) {
1669 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001670 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001671 return d;
1672 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001673 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001674 }
1675 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001676 if (FileData.cFileName[0] == '.' &&
1677 (FileData.cFileName[1] == '\0' ||
1678 FileData.cFileName[1] == '.' &&
1679 FileData.cFileName[2] == '\0'))
1680 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001681 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001682 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001683 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001684 d = NULL;
1685 break;
1686 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 if (PyList_Append(d, v) != 0) {
1688 Py_DECREF(v);
1689 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001690 d = NULL;
1691 break;
1692 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001693 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001694 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1695
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001696 if (FindClose(hFindFile) == FALSE) {
1697 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001698 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001699 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001700
1701 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001702
Tim Peters0bb44a42000-09-15 07:44:49 +00001703#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001704
1705#ifndef MAX_PATH
1706#define MAX_PATH CCHMAXPATH
1707#endif
1708 char *name, *pt;
1709 int len;
1710 PyObject *d, *v;
1711 char namebuf[MAX_PATH+5];
1712 HDIR hdir = 1;
1713 ULONG srchcnt = 1;
1714 FILEFINDBUF3 ep;
1715 APIRET rc;
1716
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001717 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001718 return NULL;
1719 if (len >= MAX_PATH) {
1720 PyErr_SetString(PyExc_ValueError, "path too long");
1721 return NULL;
1722 }
1723 strcpy(namebuf, name);
1724 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001725 if (*pt == ALTSEP)
1726 *pt = SEP;
1727 if (namebuf[len-1] != SEP)
1728 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001729 strcpy(namebuf + len, "*.*");
1730
1731 if ((d = PyList_New(0)) == NULL)
1732 return NULL;
1733
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001734 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1735 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001736 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001737 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1738 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1739 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001740
1741 if (rc != NO_ERROR) {
1742 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001743 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001744 }
1745
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001746 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001747 do {
1748 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001749 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001750 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001751
1752 strcpy(namebuf, ep.achName);
1753
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001754 /* Leave Case of Name Alone -- In Native Form */
1755 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001756
1757 v = PyString_FromString(namebuf);
1758 if (v == NULL) {
1759 Py_DECREF(d);
1760 d = NULL;
1761 break;
1762 }
1763 if (PyList_Append(d, v) != 0) {
1764 Py_DECREF(v);
1765 Py_DECREF(d);
1766 d = NULL;
1767 break;
1768 }
1769 Py_DECREF(v);
1770 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1771 }
1772
1773 return d;
1774#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001775
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001776 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001777 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001778 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001779 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001780 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001782 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001783 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001784 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001785 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001786 closedir(dirp);
1787 return NULL;
1788 }
1789 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001790 if (ep->d_name[0] == '.' &&
1791 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001792 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001793 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001794 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001795 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001796 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001797 d = NULL;
1798 break;
1799 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001800 if (PyList_Append(d, v) != 0) {
1801 Py_DECREF(v);
1802 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803 d = NULL;
1804 break;
1805 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001806 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001807 }
1808 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001809
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001810 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001811
Tim Peters0bb44a42000-09-15 07:44:49 +00001812#endif /* which OS */
1813} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001814
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001815#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001816/* A helper function for abspath on win32 */
1817static PyObject *
1818posix__getfullpathname(PyObject *self, PyObject *args)
1819{
1820 /* assume encoded strings wont more than double no of chars */
1821 char inbuf[MAX_PATH*2];
1822 char *inbufp = inbuf;
1823 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1824 char outbuf[MAX_PATH*2];
1825 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#ifdef Py_WIN_WIDE_FILENAMES
1827 if (unicode_file_names()) {
1828 PyUnicodeObject *po;
1829 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1830 Py_UNICODE woutbuf[MAX_PATH*2];
1831 Py_UNICODE *wtemp;
1832 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1833 sizeof(woutbuf)/sizeof(woutbuf[0]),
1834 woutbuf, &wtemp))
1835 return win32_error("GetFullPathName", "");
1836 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1837 }
1838 /* Drop the argument parsing error as narrow strings
1839 are also valid. */
1840 PyErr_Clear();
1841 }
1842#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001843 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1844 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001845 &insize))
1846 return NULL;
1847 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1848 outbuf, &temp))
1849 return win32_error("GetFullPathName", inbuf);
1850 return PyString_FromString(outbuf);
1851} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001852#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001855"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001856Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001857
Barry Warsaw53699e91996-12-10 23:23:01 +00001858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001859posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001860{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001861 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001862 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001863 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001864
1865#ifdef Py_WIN_WIDE_FILENAMES
1866 if (unicode_file_names()) {
1867 PyUnicodeObject *po;
1868 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1869 Py_BEGIN_ALLOW_THREADS
1870 /* PyUnicode_AS_UNICODE OK without thread lock as
1871 it is a simple dereference. */
1872 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1873 Py_END_ALLOW_THREADS
1874 if (res < 0)
1875 return posix_error();
1876 Py_INCREF(Py_None);
1877 return Py_None;
1878 }
1879 /* Drop the argument parsing error as narrow strings
1880 are also valid. */
1881 PyErr_Clear();
1882 }
1883#endif
1884
Tim Peters5aa91602002-01-30 05:46:57 +00001885 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001886 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001887 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001888 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001889#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001890 res = mkdir(path);
1891#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001892 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001893#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001895 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001896 return posix_error_with_allocated_filename(path);
1897 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 Py_INCREF(Py_None);
1899 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001900}
1901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001902
Guido van Rossumb6775db1994-08-01 11:34:53 +00001903#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001904#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1905#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1906#include <sys/resource.h>
1907#endif
1908#endif
1909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001910PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001911"nice(inc) -> new_priority\n\n\
1912Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001913
Barry Warsaw53699e91996-12-10 23:23:01 +00001914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001915posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001916{
1917 int increment, value;
1918
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001919 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001920 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001921
1922 /* There are two flavours of 'nice': one that returns the new
1923 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001924 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1925 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001926
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001927 If we are of the nice family that returns the new priority, we
1928 need to clear errno before the call, and check if errno is filled
1929 before calling posix_error() on a returnvalue of -1, because the
1930 -1 may be the actual new priority! */
1931
1932 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001933 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001934#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001935 if (value == 0)
1936 value = getpriority(PRIO_PROCESS, 0);
1937#endif
1938 if (value == -1 && errno != 0)
1939 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001940 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001941 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001942}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001943#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001946PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001947"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001948Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Barry Warsaw53699e91996-12-10 23:23:01 +00001950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001951posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001952{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001953#ifdef MS_WINDOWS
1954 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1955#else
1956 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1957#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001958}
1959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001962"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001963Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001964
Barry Warsaw53699e91996-12-10 23:23:01 +00001965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001966posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001967{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001968#ifdef MS_WINDOWS
1969 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1970#else
1971 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1972#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001973}
1974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001975
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001976PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001977"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001979
Barry Warsaw53699e91996-12-10 23:23:01 +00001980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001981posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001982{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001983#ifdef MS_WINDOWS
1984 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1985#else
1986 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1987#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988}
1989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001990
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001991#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001993"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001994Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001995
Barry Warsaw53699e91996-12-10 23:23:01 +00001996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001997posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001998{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001999 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002000 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002001 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002002 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002003 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002004 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002005 Py_END_ALLOW_THREADS
2006 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002007}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002008#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Barry Warsaw53699e91996-12-10 23:23:01 +00002015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017{
2018 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002019 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002020 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002021 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002022 if (i < 0)
2023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002025}
2026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002029"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002030Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002033"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002035
Barry Warsaw53699e91996-12-10 23:23:01 +00002036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002037posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002038{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002039#ifdef MS_WINDOWS
2040 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2041#else
2042 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2043#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044}
2045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Guido van Rossumb6775db1994-08-01 11:34:53 +00002047#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002049"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002051
Barry Warsaw53699e91996-12-10 23:23:01 +00002052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002053posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002054{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002055 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002056 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002057 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002058 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002059 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002060 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002061 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002062 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002063 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002064 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002065 u.sysname,
2066 u.nodename,
2067 u.release,
2068 u.version,
2069 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002070}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002072
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002073static int
2074extract_time(PyObject *t, long* sec, long* usec)
2075{
2076 long intval;
2077 if (PyFloat_Check(t)) {
2078 double tval = PyFloat_AsDouble(t);
2079 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2080 if (!intobj)
2081 return -1;
2082 intval = PyInt_AsLong(intobj);
2083 Py_DECREF(intobj);
2084 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002085 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002086 if (*usec < 0)
2087 /* If rounding gave us a negative number,
2088 truncate. */
2089 *usec = 0;
2090 return 0;
2091 }
2092 intval = PyInt_AsLong(t);
2093 if (intval == -1 && PyErr_Occurred())
2094 return -1;
2095 *sec = intval;
2096 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002097 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002098}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002099
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002100PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002101"utime(path, (atime, utime))\n\
2102utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002103Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002104second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002105
Barry Warsaw53699e91996-12-10 23:23:01 +00002106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002107posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002109 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002110 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002111 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002112 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002113
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002114#if defined(HAVE_UTIMES)
2115 struct timeval buf[2];
2116#define ATIME buf[0].tv_sec
2117#define MTIME buf[1].tv_sec
2118#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002119/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002120 struct utimbuf buf;
2121#define ATIME buf.actime
2122#define MTIME buf.modtime
2123#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002124#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002125 time_t buf[2];
2126#define ATIME buf[0]
2127#define MTIME buf[1]
2128#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002129#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002130
Barry Warsaw3cef8562000-05-01 16:17:24 +00002131 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002132 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002133 if (arg == Py_None) {
2134 /* optional time values not given */
2135 Py_BEGIN_ALLOW_THREADS
2136 res = utime(path, NULL);
2137 Py_END_ALLOW_THREADS
2138 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002139 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002140 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002141 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002142 return NULL;
2143 }
2144 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002145 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2146 &atime, &ausec) == -1)
2147 return NULL;
2148 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2149 &mtime, &musec) == -1)
2150 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002151 ATIME = atime;
2152 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002153#ifdef HAVE_UTIMES
2154 buf[0].tv_usec = ausec;
2155 buf[1].tv_usec = musec;
2156 Py_BEGIN_ALLOW_THREADS
2157 res = utimes(path, buf);
2158 Py_END_ALLOW_THREADS
2159#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002160 Py_BEGIN_ALLOW_THREADS
2161 res = utime(path, UTIME_ARG);
2162 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002163#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002164 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002165 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002166 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002167 Py_INCREF(Py_None);
2168 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002169#undef UTIME_ARG
2170#undef ATIME
2171#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002172}
2173
Guido van Rossum85e3b011991-06-03 12:42:10 +00002174
Guido van Rossum3b066191991-06-04 19:40:25 +00002175/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002177PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002178"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002179Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002180
Barry Warsaw53699e91996-12-10 23:23:01 +00002181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002182posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183{
2184 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002185 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002186 return NULL;
2187 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002188 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002189}
2190
Martin v. Löwis114619e2002-10-07 06:44:21 +00002191#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2192static void
2193free_string_array(char **array, int count)
2194{
2195 int i;
2196 for (i = 0; i < count; i++)
2197 PyMem_Free(array[i]);
2198 PyMem_DEL(array);
2199}
2200#endif
2201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002202
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002203#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002204PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002205"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206Execute an executable path with arguments, replacing current process.\n\
2207\n\
2208 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002209 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Barry Warsaw53699e91996-12-10 23:23:01 +00002211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002212posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002213{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002214 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002215 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002216 char **argvlist;
2217 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002218 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002219
Guido van Rossum89b33251993-10-22 14:26:06 +00002220 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002221 argv is a list or tuple of strings. */
2222
Martin v. Löwis114619e2002-10-07 06:44:21 +00002223 if (!PyArg_ParseTuple(args, "etO:execv",
2224 Py_FileSystemDefaultEncoding,
2225 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002226 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002227 if (PyList_Check(argv)) {
2228 argc = PyList_Size(argv);
2229 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002230 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002231 else if (PyTuple_Check(argv)) {
2232 argc = PyTuple_Size(argv);
2233 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002234 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002235 else {
Fred Drake661ea262000-10-24 19:57:45 +00002236 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002237 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002238 return NULL;
2239 }
2240
2241 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002242 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002243 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002244 return NULL;
2245 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002246
Barry Warsaw53699e91996-12-10 23:23:01 +00002247 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002248 if (argvlist == NULL) {
2249 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002250 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002251 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002252 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002253 if (!PyArg_Parse((*getitem)(argv, i), "et",
2254 Py_FileSystemDefaultEncoding,
2255 &argvlist[i])) {
2256 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002257 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002258 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002259 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002260 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002261
Guido van Rossum85e3b011991-06-03 12:42:10 +00002262 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002263 }
2264 argvlist[argc] = NULL;
2265
Guido van Rossumb6775db1994-08-01 11:34:53 +00002266#ifdef BAD_EXEC_PROTOTYPES
2267 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002268#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002269 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002270#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002271
Guido van Rossum85e3b011991-06-03 12:42:10 +00002272 /* If we get here it's definitely an error */
2273
Martin v. Löwis114619e2002-10-07 06:44:21 +00002274 free_string_array(argvlist, argc);
2275 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002276 return posix_error();
2277}
2278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002280PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002281"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282Execute a path with arguments and environment, replacing current process.\n\
2283\n\
2284 path: path of executable file\n\
2285 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002287
Barry Warsaw53699e91996-12-10 23:23:01 +00002288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002289posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002290{
2291 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002292 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002293 char **argvlist;
2294 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002295 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002296 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002297 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002298 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002299
2300 /* execve has three arguments: (path, argv, env), where
2301 argv is a list or tuple of strings and env is a dictionary
2302 like posix.environ. */
2303
Martin v. Löwis114619e2002-10-07 06:44:21 +00002304 if (!PyArg_ParseTuple(args, "etOO:execve",
2305 Py_FileSystemDefaultEncoding,
2306 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002307 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002308 if (PyList_Check(argv)) {
2309 argc = PyList_Size(argv);
2310 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002311 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002312 else if (PyTuple_Check(argv)) {
2313 argc = PyTuple_Size(argv);
2314 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002315 }
2316 else {
Fred Drake661ea262000-10-24 19:57:45 +00002317 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002318 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002319 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002320 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002321 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002322 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002323 }
2324
Guido van Rossum50422b42000-04-26 20:34:28 +00002325 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002326 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002327 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002328 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002329 }
2330
Barry Warsaw53699e91996-12-10 23:23:01 +00002331 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002332 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002333 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002335 }
2336 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002337 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002338 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002339 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002340 &argvlist[i]))
2341 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002342 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002343 goto fail_1;
2344 }
2345 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002346 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002347 argvlist[argc] = NULL;
2348
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002349 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002350 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002351 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002352 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002353 goto fail_1;
2354 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002355 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002356 keys = PyMapping_Keys(env);
2357 vals = PyMapping_Values(env);
2358 if (!keys || !vals)
2359 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002360
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002361 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002362 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002363 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002364
2365 key = PyList_GetItem(keys, pos);
2366 val = PyList_GetItem(vals, pos);
2367 if (!key || !val)
2368 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002369
Fred Drake661ea262000-10-24 19:57:45 +00002370 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2371 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002372 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002373 goto fail_2;
2374 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002375
2376#if defined(PYOS_OS2)
2377 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2378 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2379#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002380 len = PyString_Size(key) + PyString_Size(val) + 2;
2381 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002382 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002383 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002384 goto fail_2;
2385 }
Tim Petersc8996f52001-12-03 20:41:00 +00002386 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002387 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002388#if defined(PYOS_OS2)
2389 }
2390#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002391 }
2392 envlist[envc] = 0;
2393
Guido van Rossumb6775db1994-08-01 11:34:53 +00002394
2395#ifdef BAD_EXEC_PROTOTYPES
2396 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002397#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002398 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002399#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002400
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002401 /* If we get here it's definitely an error */
2402
2403 (void) posix_error();
2404
2405 fail_2:
2406 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002407 PyMem_DEL(envlist[envc]);
2408 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002409 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002410 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002411 Py_XDECREF(vals);
2412 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002413 fail_0:
2414 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002415 return NULL;
2416}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002417#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002419
Guido van Rossuma1065681999-01-25 23:20:23 +00002420#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002421PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002422"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002423Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002424\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002425 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002426 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002428
2429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002430posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002431{
2432 char *path;
2433 PyObject *argv;
2434 char **argvlist;
2435 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002436 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002437 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002438
2439 /* spawnv has three arguments: (mode, path, argv), where
2440 argv is a list or tuple of strings. */
2441
Martin v. Löwis114619e2002-10-07 06:44:21 +00002442 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2443 Py_FileSystemDefaultEncoding,
2444 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002445 return NULL;
2446 if (PyList_Check(argv)) {
2447 argc = PyList_Size(argv);
2448 getitem = PyList_GetItem;
2449 }
2450 else if (PyTuple_Check(argv)) {
2451 argc = PyTuple_Size(argv);
2452 getitem = PyTuple_GetItem;
2453 }
2454 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002455 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002456 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002457 return NULL;
2458 }
2459
2460 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002461 if (argvlist == NULL) {
2462 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002463 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002464 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002465 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002466 if (!PyArg_Parse((*getitem)(argv, i), "et",
2467 Py_FileSystemDefaultEncoding,
2468 &argvlist[i])) {
2469 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002470 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002471 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002472 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002473 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002474 }
2475 }
2476 argvlist[argc] = NULL;
2477
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002478#if defined(PYOS_OS2) && defined(PYCC_GCC)
2479 Py_BEGIN_ALLOW_THREADS
2480 spawnval = spawnv(mode, path, argvlist);
2481 Py_END_ALLOW_THREADS
2482#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002483 if (mode == _OLD_P_OVERLAY)
2484 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002485
Tim Peters25059d32001-12-07 20:35:43 +00002486 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002487 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002488 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002489#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002490
Martin v. Löwis114619e2002-10-07 06:44:21 +00002491 free_string_array(argvlist, argc);
2492 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002493
Fred Drake699f3522000-06-29 21:12:41 +00002494 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002495 return posix_error();
2496 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002497#if SIZEOF_LONG == SIZEOF_VOID_P
2498 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002499#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002500 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002501#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002502}
2503
2504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002505PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002506"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002507Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002508\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002509 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002510 path: path of executable file\n\
2511 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002512 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002513
2514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002515posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002516{
2517 char *path;
2518 PyObject *argv, *env;
2519 char **argvlist;
2520 char **envlist;
2521 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2522 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002523 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002524 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002525 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002526
2527 /* spawnve has four arguments: (mode, path, argv, env), where
2528 argv is a list or tuple of strings and env is a dictionary
2529 like posix.environ. */
2530
Martin v. Löwis114619e2002-10-07 06:44:21 +00002531 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2532 Py_FileSystemDefaultEncoding,
2533 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002534 return NULL;
2535 if (PyList_Check(argv)) {
2536 argc = PyList_Size(argv);
2537 getitem = PyList_GetItem;
2538 }
2539 else if (PyTuple_Check(argv)) {
2540 argc = PyTuple_Size(argv);
2541 getitem = PyTuple_GetItem;
2542 }
2543 else {
Fred Drake661ea262000-10-24 19:57:45 +00002544 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002545 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002546 }
2547 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002548 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002549 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002550 }
2551
2552 argvlist = PyMem_NEW(char *, argc+1);
2553 if (argvlist == NULL) {
2554 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002555 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002556 }
2557 for (i = 0; i < argc; i++) {
2558 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002559 "et;spawnve() arg 2 must contain only strings",
2560 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002561 &argvlist[i]))
2562 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002563 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002564 goto fail_1;
2565 }
2566 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002567 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002568 argvlist[argc] = NULL;
2569
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002570 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002571 envlist = PyMem_NEW(char *, i + 1);
2572 if (envlist == NULL) {
2573 PyErr_NoMemory();
2574 goto fail_1;
2575 }
2576 envc = 0;
2577 keys = PyMapping_Keys(env);
2578 vals = PyMapping_Values(env);
2579 if (!keys || !vals)
2580 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002581
Guido van Rossuma1065681999-01-25 23:20:23 +00002582 for (pos = 0; pos < i; pos++) {
2583 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002584 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002585
2586 key = PyList_GetItem(keys, pos);
2587 val = PyList_GetItem(vals, pos);
2588 if (!key || !val)
2589 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002590
Fred Drake661ea262000-10-24 19:57:45 +00002591 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2592 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002593 {
2594 goto fail_2;
2595 }
Tim Petersc8996f52001-12-03 20:41:00 +00002596 len = PyString_Size(key) + PyString_Size(val) + 2;
2597 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002598 if (p == NULL) {
2599 PyErr_NoMemory();
2600 goto fail_2;
2601 }
Tim Petersc8996f52001-12-03 20:41:00 +00002602 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002603 envlist[envc++] = p;
2604 }
2605 envlist[envc] = 0;
2606
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002607#if defined(PYOS_OS2) && defined(PYCC_GCC)
2608 Py_BEGIN_ALLOW_THREADS
2609 spawnval = spawnve(mode, path, argvlist, envlist);
2610 Py_END_ALLOW_THREADS
2611#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002612 if (mode == _OLD_P_OVERLAY)
2613 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002614
2615 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002616 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002617 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002618#endif
Tim Peters25059d32001-12-07 20:35:43 +00002619
Fred Drake699f3522000-06-29 21:12:41 +00002620 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002621 (void) posix_error();
2622 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002623#if SIZEOF_LONG == SIZEOF_VOID_P
2624 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002625#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002626 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002627#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002628
2629 fail_2:
2630 while (--envc >= 0)
2631 PyMem_DEL(envlist[envc]);
2632 PyMem_DEL(envlist);
2633 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002634 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002635 Py_XDECREF(vals);
2636 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002637 fail_0:
2638 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002639 return res;
2640}
2641#endif /* HAVE_SPAWNV */
2642
2643
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002644#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002645PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002646"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002647Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2648\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002650
2651static PyObject *
2652posix_fork1(self, args)
2653 PyObject *self;
2654 PyObject *args;
2655{
2656 int pid;
2657 if (!PyArg_ParseTuple(args, ":fork1"))
2658 return NULL;
2659 pid = fork1();
2660 if (pid == -1)
2661 return posix_error();
2662 PyOS_AfterFork();
2663 return PyInt_FromLong((long)pid);
2664}
2665#endif
2666
2667
Guido van Rossumad0ee831995-03-01 10:34:45 +00002668#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002670"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002671Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002672Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002673
Barry Warsaw53699e91996-12-10 23:23:01 +00002674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002675posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002676{
2677 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002678 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002679 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002680 pid = fork();
2681 if (pid == -1)
2682 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002683 if (pid == 0)
2684 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002685 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002686}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002687#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002688
Fred Drake8cef4cf2000-06-28 16:40:38 +00002689#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2690#ifdef HAVE_PTY_H
2691#include <pty.h>
2692#else
2693#ifdef HAVE_LIBUTIL_H
2694#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002695#endif /* HAVE_LIBUTIL_H */
2696#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002697#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002698
Thomas Wouters70c21a12000-07-14 14:28:33 +00002699#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002701"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002703
2704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002705posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002706{
2707 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002708#ifndef HAVE_OPENPTY
2709 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002710#endif
2711
Fred Drake8cef4cf2000-06-28 16:40:38 +00002712 if (!PyArg_ParseTuple(args, ":openpty"))
2713 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002714
2715#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002716 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2717 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002718#else
2719 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2720 if (slave_name == NULL)
2721 return posix_error();
2722
2723 slave_fd = open(slave_name, O_RDWR);
2724 if (slave_fd < 0)
2725 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002726#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002727
Fred Drake8cef4cf2000-06-28 16:40:38 +00002728 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002729
Fred Drake8cef4cf2000-06-28 16:40:38 +00002730}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002731#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002732
2733#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002734PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002735"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002736Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2737Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002739
2740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002741posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002742{
2743 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002744
Fred Drake8cef4cf2000-06-28 16:40:38 +00002745 if (!PyArg_ParseTuple(args, ":forkpty"))
2746 return NULL;
2747 pid = forkpty(&master_fd, NULL, NULL, NULL);
2748 if (pid == -1)
2749 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002750 if (pid == 0)
2751 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002752 return Py_BuildValue("(ii)", pid, master_fd);
2753}
2754#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002755
Guido van Rossumad0ee831995-03-01 10:34:45 +00002756#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002758"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002759Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Barry Warsaw53699e91996-12-10 23:23:01 +00002761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002762posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002763{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002764 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002766 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002768#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Guido van Rossumad0ee831995-03-01 10:34:45 +00002771#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002772PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002773"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002774Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002775
Barry Warsaw53699e91996-12-10 23:23:01 +00002776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002777posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002778{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002779 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002780 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002781 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002782}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002783#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002785
Guido van Rossumad0ee831995-03-01 10:34:45 +00002786#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002788"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Barry Warsaw53699e91996-12-10 23:23:01 +00002791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002792posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002793{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002794 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002795 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002796 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002797}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002798#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002799
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002800
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002801PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002802"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002804
Barry Warsaw53699e91996-12-10 23:23:01 +00002805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002806posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002807{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002808 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002809 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002810 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002811}
2812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002813
Fred Drakec9680921999-12-13 16:37:25 +00002814#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002816"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002817Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002818
2819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002820posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002821{
2822 PyObject *result = NULL;
2823
2824 if (PyArg_ParseTuple(args, ":getgroups")) {
2825#ifdef NGROUPS_MAX
2826#define MAX_GROUPS NGROUPS_MAX
2827#else
2828 /* defined to be 16 on Solaris7, so this should be a small number */
2829#define MAX_GROUPS 64
2830#endif
2831 gid_t grouplist[MAX_GROUPS];
2832 int n;
2833
2834 n = getgroups(MAX_GROUPS, grouplist);
2835 if (n < 0)
2836 posix_error();
2837 else {
2838 result = PyList_New(n);
2839 if (result != NULL) {
2840 PyObject *o;
2841 int i;
2842 for (i = 0; i < n; ++i) {
2843 o = PyInt_FromLong((long)grouplist[i]);
2844 if (o == NULL) {
2845 Py_DECREF(result);
2846 result = NULL;
2847 break;
2848 }
2849 PyList_SET_ITEM(result, i, o);
2850 }
2851 }
2852 }
2853 }
2854 return result;
2855}
2856#endif
2857
Martin v. Löwis606edc12002-06-13 21:09:11 +00002858#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002859PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002860"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002861Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002862
2863static PyObject *
2864posix_getpgid(PyObject *self, PyObject *args)
2865{
2866 int pid, pgid;
2867 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2868 return NULL;
2869 pgid = getpgid(pid);
2870 if (pgid < 0)
2871 return posix_error();
2872 return PyInt_FromLong((long)pgid);
2873}
2874#endif /* HAVE_GETPGID */
2875
2876
Guido van Rossumb6775db1994-08-01 11:34:53 +00002877#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002881
Barry Warsaw53699e91996-12-10 23:23:01 +00002882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002883posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002884{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002885 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002886 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002887#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002888 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002889#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002890 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002891#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002892}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002893#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002895
Guido van Rossumb6775db1994-08-01 11:34:53 +00002896#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002897PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002898"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002899Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002900
Barry Warsaw53699e91996-12-10 23:23:01 +00002901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002902posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002903{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002904 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002905 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002906#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002907 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002908#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002909 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002910#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002911 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002912 Py_INCREF(Py_None);
2913 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002914}
2915
Guido van Rossumb6775db1994-08-01 11:34:53 +00002916#endif /* HAVE_SETPGRP */
2917
Guido van Rossumad0ee831995-03-01 10:34:45 +00002918#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002919PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002920"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002921Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002922
Barry Warsaw53699e91996-12-10 23:23:01 +00002923static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002924posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002925{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002926 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002927 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002928 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002929}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002930#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002932
Fred Drake12c6e2d1999-12-14 21:25:03 +00002933#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002934PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002935"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002937
2938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002939posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002940{
2941 PyObject *result = NULL;
2942
2943 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002944 char *name;
2945 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002946
Fred Drakea30680b2000-12-06 21:24:28 +00002947 errno = 0;
2948 name = getlogin();
2949 if (name == NULL) {
2950 if (errno)
2951 posix_error();
2952 else
2953 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002954 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002955 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002956 else
2957 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002958 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002959 }
2960 return result;
2961}
2962#endif
2963
Guido van Rossumad0ee831995-03-01 10:34:45 +00002964#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002966"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002967Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002968
Barry Warsaw53699e91996-12-10 23:23:01 +00002969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002970posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002971{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002972 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002973 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002974 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002975}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002976#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Guido van Rossumad0ee831995-03-01 10:34:45 +00002979#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002980PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002981"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002982Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983
Barry Warsaw53699e91996-12-10 23:23:01 +00002984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002985posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002986{
2987 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002988 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002989 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002990#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002991 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2992 APIRET rc;
2993 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002994 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002995
2996 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2997 APIRET rc;
2998 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002999 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003000
3001 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003002 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003003#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003004 if (kill(pid, sig) == -1)
3005 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003006#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003007 Py_INCREF(Py_None);
3008 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003009}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003010#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003011
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003012#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003014"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003015Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003016
3017static PyObject *
3018posix_killpg(PyObject *self, PyObject *args)
3019{
3020 int pgid, sig;
3021 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3022 return NULL;
3023 if (killpg(pgid, sig) == -1)
3024 return posix_error();
3025 Py_INCREF(Py_None);
3026 return Py_None;
3027}
3028#endif
3029
Guido van Rossumc0125471996-06-28 18:55:32 +00003030#ifdef HAVE_PLOCK
3031
3032#ifdef HAVE_SYS_LOCK_H
3033#include <sys/lock.h>
3034#endif
3035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003036PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003037"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003038Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Barry Warsaw53699e91996-12-10 23:23:01 +00003040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003041posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003042{
3043 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003044 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003045 return NULL;
3046 if (plock(op) == -1)
3047 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 Py_INCREF(Py_None);
3049 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003050}
3051#endif
3052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003054#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003055PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003056"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003057Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003058
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003059#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003060#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003061static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003062async_system(const char *command)
3063{
3064 char *p, errormsg[256], args[1024];
3065 RESULTCODES rcodes;
3066 APIRET rc;
3067 char *shell = getenv("COMSPEC");
3068 if (!shell)
3069 shell = "cmd";
3070
3071 strcpy(args, shell);
3072 p = &args[ strlen(args)+1 ];
3073 strcpy(p, "/c ");
3074 strcat(p, command);
3075 p += strlen(p) + 1;
3076 *p = '\0';
3077
3078 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003079 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003080 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003081 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003082 &rcodes, shell);
3083 return rc;
3084}
3085
Guido van Rossumd48f2521997-12-05 22:19:34 +00003086static FILE *
3087popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003088{
3089 HFILE rhan, whan;
3090 FILE *retfd = NULL;
3091 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3092
Guido van Rossumd48f2521997-12-05 22:19:34 +00003093 if (rc != NO_ERROR) {
3094 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003095 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003096 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003097
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003098 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3099 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003100
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003101 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3102 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003103
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003104 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3105 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003106
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003107 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003108 }
3109
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003110 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3111 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003112
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003113 if (rc == NO_ERROR)
3114 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3115
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003116 close(oldfd); /* And Close Saved STDOUT Handle */
3117 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003118
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003119 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3120 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003121
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003122 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3123 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003124
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003125 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3126 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003127
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003128 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003129 }
3130
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003131 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3132 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003133
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003134 if (rc == NO_ERROR)
3135 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3136
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003137 close(oldfd); /* And Close Saved STDIN Handle */
3138 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003139
Guido van Rossumd48f2521997-12-05 22:19:34 +00003140 } else {
3141 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003142 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003143 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003144}
3145
3146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003147posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003148{
3149 char *name;
3150 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003152 FILE *fp;
3153 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003154 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003155 return NULL;
3156 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003157 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003158 Py_END_ALLOW_THREADS
3159 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003160 return os2_error(err);
3161
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003162 f = PyFile_FromFile(fp, name, mode, fclose);
3163 if (f != NULL)
3164 PyFile_SetBufSize(f, bufsize);
3165 return f;
3166}
3167
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003168#elif defined(PYCC_GCC)
3169
3170/* standard posix version of popen() support */
3171static PyObject *
3172posix_popen(PyObject *self, PyObject *args)
3173{
3174 char *name;
3175 char *mode = "r";
3176 int bufsize = -1;
3177 FILE *fp;
3178 PyObject *f;
3179 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3180 return NULL;
3181 Py_BEGIN_ALLOW_THREADS
3182 fp = popen(name, mode);
3183 Py_END_ALLOW_THREADS
3184 if (fp == NULL)
3185 return posix_error();
3186 f = PyFile_FromFile(fp, name, mode, pclose);
3187 if (f != NULL)
3188 PyFile_SetBufSize(f, bufsize);
3189 return f;
3190}
3191
3192/* fork() under OS/2 has lots'o'warts
3193 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3194 * most of this code is a ripoff of the win32 code, but using the
3195 * capabilities of EMX's C library routines
3196 */
3197
3198/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3199#define POPEN_1 1
3200#define POPEN_2 2
3201#define POPEN_3 3
3202#define POPEN_4 4
3203
3204static PyObject *_PyPopen(char *, int, int, int);
3205static int _PyPclose(FILE *file);
3206
3207/*
3208 * Internal dictionary mapping popen* file pointers to process handles,
3209 * for use when retrieving the process exit code. See _PyPclose() below
3210 * for more information on this dictionary's use.
3211 */
3212static PyObject *_PyPopenProcs = NULL;
3213
3214/* os2emx version of popen2()
3215 *
3216 * The result of this function is a pipe (file) connected to the
3217 * process's stdin, and a pipe connected to the process's stdout.
3218 */
3219
3220static PyObject *
3221os2emx_popen2(PyObject *self, PyObject *args)
3222{
3223 PyObject *f;
3224 int tm=0;
3225
3226 char *cmdstring;
3227 char *mode = "t";
3228 int bufsize = -1;
3229 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3230 return NULL;
3231
3232 if (*mode == 't')
3233 tm = O_TEXT;
3234 else if (*mode != 'b') {
3235 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3236 return NULL;
3237 } else
3238 tm = O_BINARY;
3239
3240 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3241
3242 return f;
3243}
3244
3245/*
3246 * Variation on os2emx.popen2
3247 *
3248 * The result of this function is 3 pipes - the process's stdin,
3249 * stdout and stderr
3250 */
3251
3252static PyObject *
3253os2emx_popen3(PyObject *self, PyObject *args)
3254{
3255 PyObject *f;
3256 int tm = 0;
3257
3258 char *cmdstring;
3259 char *mode = "t";
3260 int bufsize = -1;
3261 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3262 return NULL;
3263
3264 if (*mode == 't')
3265 tm = O_TEXT;
3266 else if (*mode != 'b') {
3267 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3268 return NULL;
3269 } else
3270 tm = O_BINARY;
3271
3272 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3273
3274 return f;
3275}
3276
3277/*
3278 * Variation on os2emx.popen2
3279 *
3280 * The result of this function is 2 pipes - the processes stdin,
3281 * and stdout+stderr combined as a single pipe.
3282 */
3283
3284static PyObject *
3285os2emx_popen4(PyObject *self, PyObject *args)
3286{
3287 PyObject *f;
3288 int tm = 0;
3289
3290 char *cmdstring;
3291 char *mode = "t";
3292 int bufsize = -1;
3293 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3294 return NULL;
3295
3296 if (*mode == 't')
3297 tm = O_TEXT;
3298 else if (*mode != 'b') {
3299 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3300 return NULL;
3301 } else
3302 tm = O_BINARY;
3303
3304 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3305
3306 return f;
3307}
3308
3309/* a couple of structures for convenient handling of multiple
3310 * file handles and pipes
3311 */
3312struct file_ref
3313{
3314 int handle;
3315 int flags;
3316};
3317
3318struct pipe_ref
3319{
3320 int rd;
3321 int wr;
3322};
3323
3324/* The following code is derived from the win32 code */
3325
3326static PyObject *
3327_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3328{
3329 struct file_ref stdio[3];
3330 struct pipe_ref p_fd[3];
3331 FILE *p_s[3];
3332 int file_count, i, pipe_err, pipe_pid;
3333 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3334 PyObject *f, *p_f[3];
3335
3336 /* file modes for subsequent fdopen's on pipe handles */
3337 if (mode == O_TEXT)
3338 {
3339 rd_mode = "rt";
3340 wr_mode = "wt";
3341 }
3342 else
3343 {
3344 rd_mode = "rb";
3345 wr_mode = "wb";
3346 }
3347
3348 /* prepare shell references */
3349 if ((shell = getenv("EMXSHELL")) == NULL)
3350 if ((shell = getenv("COMSPEC")) == NULL)
3351 {
3352 errno = ENOENT;
3353 return posix_error();
3354 }
3355
3356 sh_name = _getname(shell);
3357 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3358 opt = "/c";
3359 else
3360 opt = "-c";
3361
3362 /* save current stdio fds + their flags, and set not inheritable */
3363 i = pipe_err = 0;
3364 while (pipe_err >= 0 && i < 3)
3365 {
3366 pipe_err = stdio[i].handle = dup(i);
3367 stdio[i].flags = fcntl(i, F_GETFD, 0);
3368 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3369 i++;
3370 }
3371 if (pipe_err < 0)
3372 {
3373 /* didn't get them all saved - clean up and bail out */
3374 int saved_err = errno;
3375 while (i-- > 0)
3376 {
3377 close(stdio[i].handle);
3378 }
3379 errno = saved_err;
3380 return posix_error();
3381 }
3382
3383 /* create pipe ends */
3384 file_count = 2;
3385 if (n == POPEN_3)
3386 file_count = 3;
3387 i = pipe_err = 0;
3388 while ((pipe_err == 0) && (i < file_count))
3389 pipe_err = pipe((int *)&p_fd[i++]);
3390 if (pipe_err < 0)
3391 {
3392 /* didn't get them all made - clean up and bail out */
3393 while (i-- > 0)
3394 {
3395 close(p_fd[i].wr);
3396 close(p_fd[i].rd);
3397 }
3398 errno = EPIPE;
3399 return posix_error();
3400 }
3401
3402 /* change the actual standard IO streams over temporarily,
3403 * making the retained pipe ends non-inheritable
3404 */
3405 pipe_err = 0;
3406
3407 /* - stdin */
3408 if (dup2(p_fd[0].rd, 0) == 0)
3409 {
3410 close(p_fd[0].rd);
3411 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3412 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3413 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3414 {
3415 close(p_fd[0].wr);
3416 pipe_err = -1;
3417 }
3418 }
3419 else
3420 {
3421 pipe_err = -1;
3422 }
3423
3424 /* - stdout */
3425 if (pipe_err == 0)
3426 {
3427 if (dup2(p_fd[1].wr, 1) == 1)
3428 {
3429 close(p_fd[1].wr);
3430 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3431 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3432 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3433 {
3434 close(p_fd[1].rd);
3435 pipe_err = -1;
3436 }
3437 }
3438 else
3439 {
3440 pipe_err = -1;
3441 }
3442 }
3443
3444 /* - stderr, as required */
3445 if (pipe_err == 0)
3446 switch (n)
3447 {
3448 case POPEN_3:
3449 {
3450 if (dup2(p_fd[2].wr, 2) == 2)
3451 {
3452 close(p_fd[2].wr);
3453 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3454 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3455 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3456 {
3457 close(p_fd[2].rd);
3458 pipe_err = -1;
3459 }
3460 }
3461 else
3462 {
3463 pipe_err = -1;
3464 }
3465 break;
3466 }
3467
3468 case POPEN_4:
3469 {
3470 if (dup2(1, 2) != 2)
3471 {
3472 pipe_err = -1;
3473 }
3474 break;
3475 }
3476 }
3477
3478 /* spawn the child process */
3479 if (pipe_err == 0)
3480 {
3481 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3482 if (pipe_pid == -1)
3483 {
3484 pipe_err = -1;
3485 }
3486 else
3487 {
3488 /* save the PID into the FILE structure
3489 * NOTE: this implementation doesn't actually
3490 * take advantage of this, but do it for
3491 * completeness - AIM Apr01
3492 */
3493 for (i = 0; i < file_count; i++)
3494 p_s[i]->_pid = pipe_pid;
3495 }
3496 }
3497
3498 /* reset standard IO to normal */
3499 for (i = 0; i < 3; i++)
3500 {
3501 dup2(stdio[i].handle, i);
3502 fcntl(i, F_SETFD, stdio[i].flags);
3503 close(stdio[i].handle);
3504 }
3505
3506 /* if any remnant problems, clean up and bail out */
3507 if (pipe_err < 0)
3508 {
3509 for (i = 0; i < 3; i++)
3510 {
3511 close(p_fd[i].rd);
3512 close(p_fd[i].wr);
3513 }
3514 errno = EPIPE;
3515 return posix_error_with_filename(cmdstring);
3516 }
3517
3518 /* build tuple of file objects to return */
3519 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3520 PyFile_SetBufSize(p_f[0], bufsize);
3521 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3522 PyFile_SetBufSize(p_f[1], bufsize);
3523 if (n == POPEN_3)
3524 {
3525 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3526 PyFile_SetBufSize(p_f[0], bufsize);
3527 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3528 }
3529 else
3530 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3531
3532 /*
3533 * Insert the files we've created into the process dictionary
3534 * all referencing the list with the process handle and the
3535 * initial number of files (see description below in _PyPclose).
3536 * Since if _PyPclose later tried to wait on a process when all
3537 * handles weren't closed, it could create a deadlock with the
3538 * child, we spend some energy here to try to ensure that we
3539 * either insert all file handles into the dictionary or none
3540 * at all. It's a little clumsy with the various popen modes
3541 * and variable number of files involved.
3542 */
3543 if (!_PyPopenProcs)
3544 {
3545 _PyPopenProcs = PyDict_New();
3546 }
3547
3548 if (_PyPopenProcs)
3549 {
3550 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3551 int ins_rc[3];
3552
3553 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3554 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3555
3556 procObj = PyList_New(2);
3557 pidObj = PyInt_FromLong((long) pipe_pid);
3558 intObj = PyInt_FromLong((long) file_count);
3559
3560 if (procObj && pidObj && intObj)
3561 {
3562 PyList_SetItem(procObj, 0, pidObj);
3563 PyList_SetItem(procObj, 1, intObj);
3564
3565 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3566 if (fileObj[0])
3567 {
3568 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3569 fileObj[0],
3570 procObj);
3571 }
3572 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3573 if (fileObj[1])
3574 {
3575 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3576 fileObj[1],
3577 procObj);
3578 }
3579 if (file_count >= 3)
3580 {
3581 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3582 if (fileObj[2])
3583 {
3584 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3585 fileObj[2],
3586 procObj);
3587 }
3588 }
3589
3590 if (ins_rc[0] < 0 || !fileObj[0] ||
3591 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3592 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3593 {
3594 /* Something failed - remove any dictionary
3595 * entries that did make it.
3596 */
3597 if (!ins_rc[0] && fileObj[0])
3598 {
3599 PyDict_DelItem(_PyPopenProcs,
3600 fileObj[0]);
3601 }
3602 if (!ins_rc[1] && fileObj[1])
3603 {
3604 PyDict_DelItem(_PyPopenProcs,
3605 fileObj[1]);
3606 }
3607 if (!ins_rc[2] && fileObj[2])
3608 {
3609 PyDict_DelItem(_PyPopenProcs,
3610 fileObj[2]);
3611 }
3612 }
3613 }
3614
3615 /*
3616 * Clean up our localized references for the dictionary keys
3617 * and value since PyDict_SetItem will Py_INCREF any copies
3618 * that got placed in the dictionary.
3619 */
3620 Py_XDECREF(procObj);
3621 Py_XDECREF(fileObj[0]);
3622 Py_XDECREF(fileObj[1]);
3623 Py_XDECREF(fileObj[2]);
3624 }
3625
3626 /* Child is launched. */
3627 return f;
3628}
3629
3630/*
3631 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3632 * exit code for the child process and return as a result of the close.
3633 *
3634 * This function uses the _PyPopenProcs dictionary in order to map the
3635 * input file pointer to information about the process that was
3636 * originally created by the popen* call that created the file pointer.
3637 * The dictionary uses the file pointer as a key (with one entry
3638 * inserted for each file returned by the original popen* call) and a
3639 * single list object as the value for all files from a single call.
3640 * The list object contains the Win32 process handle at [0], and a file
3641 * count at [1], which is initialized to the total number of file
3642 * handles using that list.
3643 *
3644 * This function closes whichever handle it is passed, and decrements
3645 * the file count in the dictionary for the process handle pointed to
3646 * by this file. On the last close (when the file count reaches zero),
3647 * this function will wait for the child process and then return its
3648 * exit code as the result of the close() operation. This permits the
3649 * files to be closed in any order - it is always the close() of the
3650 * final handle that will return the exit code.
3651 */
3652
3653 /* RED_FLAG 31-Aug-2000 Tim
3654 * This is always called (today!) between a pair of
3655 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3656 * macros. So the thread running this has no valid thread state, as
3657 * far as Python is concerned. However, this calls some Python API
3658 * functions that cannot be called safely without a valid thread
3659 * state, in particular PyDict_GetItem.
3660 * As a temporary hack (although it may last for years ...), we
3661 * *rely* on not having a valid thread state in this function, in
3662 * order to create our own "from scratch".
3663 * This will deadlock if _PyPclose is ever called by a thread
3664 * holding the global lock.
3665 * (The OS/2 EMX thread support appears to cover the case where the
3666 * lock is already held - AIM Apr01)
3667 */
3668
3669static int _PyPclose(FILE *file)
3670{
3671 int result;
3672 int exit_code;
3673 int pipe_pid;
3674 PyObject *procObj, *pidObj, *intObj, *fileObj;
3675 int file_count;
3676#ifdef WITH_THREAD
3677 PyInterpreterState* pInterpreterState;
3678 PyThreadState* pThreadState;
3679#endif
3680
3681 /* Close the file handle first, to ensure it can't block the
3682 * child from exiting if it's the last handle.
3683 */
3684 result = fclose(file);
3685
3686#ifdef WITH_THREAD
3687 /* Bootstrap a valid thread state into existence. */
3688 pInterpreterState = PyInterpreterState_New();
3689 if (!pInterpreterState) {
3690 /* Well, we're hosed now! We don't have a thread
3691 * state, so can't call a nice error routine, or raise
3692 * an exception. Just die.
3693 */
3694 Py_FatalError("unable to allocate interpreter state "
3695 "when closing popen object.");
3696 return -1; /* unreachable */
3697 }
3698 pThreadState = PyThreadState_New(pInterpreterState);
3699 if (!pThreadState) {
3700 Py_FatalError("unable to allocate thread state "
3701 "when closing popen object.");
3702 return -1; /* unreachable */
3703 }
3704 /* Grab the global lock. Note that this will deadlock if the
3705 * current thread already has the lock! (see RED_FLAG comments
3706 * before this function)
3707 */
3708 PyEval_RestoreThread(pThreadState);
3709#endif
3710
3711 if (_PyPopenProcs)
3712 {
3713 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3714 (procObj = PyDict_GetItem(_PyPopenProcs,
3715 fileObj)) != NULL &&
3716 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3717 (intObj = PyList_GetItem(procObj,1)) != NULL)
3718 {
3719 pipe_pid = (int) PyInt_AsLong(pidObj);
3720 file_count = (int) PyInt_AsLong(intObj);
3721
3722 if (file_count > 1)
3723 {
3724 /* Still other files referencing process */
3725 file_count--;
3726 PyList_SetItem(procObj,1,
3727 PyInt_FromLong((long) file_count));
3728 }
3729 else
3730 {
3731 /* Last file for this process */
3732 if (result != EOF &&
3733 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3734 {
3735 /* extract exit status */
3736 if (WIFEXITED(exit_code))
3737 {
3738 result = WEXITSTATUS(exit_code);
3739 }
3740 else
3741 {
3742 errno = EPIPE;
3743 result = -1;
3744 }
3745 }
3746 else
3747 {
3748 /* Indicate failure - this will cause the file object
3749 * to raise an I/O error and translate the last
3750 * error code from errno. We do have a problem with
3751 * last errors that overlap the normal errno table,
3752 * but that's a consistent problem with the file object.
3753 */
3754 result = -1;
3755 }
3756 }
3757
3758 /* Remove this file pointer from dictionary */
3759 PyDict_DelItem(_PyPopenProcs, fileObj);
3760
3761 if (PyDict_Size(_PyPopenProcs) == 0)
3762 {
3763 Py_DECREF(_PyPopenProcs);
3764 _PyPopenProcs = NULL;
3765 }
3766
3767 } /* if object retrieval ok */
3768
3769 Py_XDECREF(fileObj);
3770 } /* if _PyPopenProcs */
3771
3772#ifdef WITH_THREAD
3773 /* Tear down the thread & interpreter states.
3774 * Note that interpreter state clear & delete functions automatically
3775 * call the thread clear & delete functions, and indeed insist on
3776 * doing that themselves. The lock must be held during the clear, but
3777 * need not be held during the delete.
3778 */
3779 PyInterpreterState_Clear(pInterpreterState);
3780 PyEval_ReleaseThread(pThreadState);
3781 PyInterpreterState_Delete(pInterpreterState);
3782#endif
3783
3784 return result;
3785}
3786
3787#endif /* PYCC_??? */
3788
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003789#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003790
3791/*
3792 * Portable 'popen' replacement for Win32.
3793 *
3794 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3795 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003796 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003797 */
3798
3799#include <malloc.h>
3800#include <io.h>
3801#include <fcntl.h>
3802
3803/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3804#define POPEN_1 1
3805#define POPEN_2 2
3806#define POPEN_3 3
3807#define POPEN_4 4
3808
3809static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003810static int _PyPclose(FILE *file);
3811
3812/*
3813 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003814 * for use when retrieving the process exit code. See _PyPclose() below
3815 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003816 */
3817static PyObject *_PyPopenProcs = NULL;
3818
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003819
3820/* popen that works from a GUI.
3821 *
3822 * The result of this function is a pipe (file) connected to the
3823 * processes stdin or stdout, depending on the requested mode.
3824 */
3825
3826static PyObject *
3827posix_popen(PyObject *self, PyObject *args)
3828{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003829 PyObject *f, *s;
3830 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003831
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003832 char *cmdstring;
3833 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003834 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003835 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003836 return NULL;
3837
3838 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003839
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003840 if (*mode == 'r')
3841 tm = _O_RDONLY;
3842 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003843 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003844 return NULL;
3845 } else
3846 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003847
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003848 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003849 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003850 return NULL;
3851 }
3852
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003853 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003854 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003856 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003857 else
3858 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3859
3860 return f;
3861}
3862
3863/* Variation on win32pipe.popen
3864 *
3865 * The result of this function is a pipe (file) connected to the
3866 * process's stdin, and a pipe connected to the process's stdout.
3867 */
3868
3869static PyObject *
3870win32_popen2(PyObject *self, PyObject *args)
3871{
3872 PyObject *f;
3873 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003874
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003875 char *cmdstring;
3876 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003877 int bufsize = -1;
3878 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003879 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003880
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003881 if (*mode == 't')
3882 tm = _O_TEXT;
3883 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003884 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003885 return NULL;
3886 } else
3887 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003888
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003889 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003890 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003891 return NULL;
3892 }
3893
3894 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003895
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003896 return f;
3897}
3898
3899/*
3900 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003901 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 * The result of this function is 3 pipes - the process's stdin,
3903 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003904 */
3905
3906static PyObject *
3907win32_popen3(PyObject *self, PyObject *args)
3908{
3909 PyObject *f;
3910 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003911
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003912 char *cmdstring;
3913 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003914 int bufsize = -1;
3915 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003916 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003917
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003918 if (*mode == 't')
3919 tm = _O_TEXT;
3920 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003921 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003922 return NULL;
3923 } else
3924 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003925
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003926 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003927 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003928 return NULL;
3929 }
3930
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003931 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003932
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003933 return f;
3934}
3935
3936/*
3937 * Variation on win32pipe.popen
3938 *
Tim Peters5aa91602002-01-30 05:46:57 +00003939 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003940 * and stdout+stderr combined as a single pipe.
3941 */
3942
3943static PyObject *
3944win32_popen4(PyObject *self, PyObject *args)
3945{
3946 PyObject *f;
3947 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003948
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003949 char *cmdstring;
3950 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003951 int bufsize = -1;
3952 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003953 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003954
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003955 if (*mode == 't')
3956 tm = _O_TEXT;
3957 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003958 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003959 return NULL;
3960 } else
3961 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003962
3963 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003964 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003965 return NULL;
3966 }
3967
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003968 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003969
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003970 return f;
3971}
3972
Mark Hammond08501372001-01-31 07:30:29 +00003973static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003974_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003975 HANDLE hStdin,
3976 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003977 HANDLE hStderr,
3978 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003979{
3980 PROCESS_INFORMATION piProcInfo;
3981 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003982 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003983 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003984 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003985 int i;
3986 int x;
3987
3988 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003989 char *comshell;
3990
Tim Peters92e4dd82002-10-05 01:47:34 +00003991 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003992 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3993 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003994
3995 /* Explicitly check if we are using COMMAND.COM. If we are
3996 * then use the w9xpopen hack.
3997 */
3998 comshell = s1 + x;
3999 while (comshell >= s1 && *comshell != '\\')
4000 --comshell;
4001 ++comshell;
4002
4003 if (GetVersion() < 0x80000000 &&
4004 _stricmp(comshell, "command.com") != 0) {
4005 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004006 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004007 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004008 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004009 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004010 }
4011 else {
4012 /*
Tim Peters402d5982001-08-27 06:37:48 +00004013 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4014 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004015 */
Mark Hammond08501372001-01-31 07:30:29 +00004016 char modulepath[_MAX_PATH];
4017 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004018 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4019 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004020 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004021 x = i+1;
4022 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004023 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004024 strncat(modulepath,
4025 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004026 (sizeof(modulepath)/sizeof(modulepath[0]))
4027 -strlen(modulepath));
4028 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004029 /* Eeek - file-not-found - possibly an embedding
4030 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004031 */
Tim Peters5aa91602002-01-30 05:46:57 +00004032 strncpy(modulepath,
4033 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004034 sizeof(modulepath)/sizeof(modulepath[0]));
4035 if (modulepath[strlen(modulepath)-1] != '\\')
4036 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004037 strncat(modulepath,
4038 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004039 (sizeof(modulepath)/sizeof(modulepath[0]))
4040 -strlen(modulepath));
4041 /* No where else to look - raise an easily identifiable
4042 error, rather than leaving Windows to report
4043 "file not found" - as the user is probably blissfully
4044 unaware this shim EXE is used, and it will confuse them.
4045 (well, it confused me for a while ;-)
4046 */
4047 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004048 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004049 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004050 "for popen to work with your shell "
4051 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004052 szConsoleSpawn);
4053 return FALSE;
4054 }
4055 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004056 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004057 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004058 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004059
Tim Peters92e4dd82002-10-05 01:47:34 +00004060 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004061 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004062 /* To maintain correct argument passing semantics,
4063 we pass the command-line as it stands, and allow
4064 quoting to be applied. w9xpopen.exe will then
4065 use its argv vector, and re-quote the necessary
4066 args for the ultimate child process.
4067 */
Tim Peters75cdad52001-11-28 22:07:30 +00004068 PyOS_snprintf(
4069 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004070 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004071 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004072 s1,
4073 s3,
4074 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004075 /* Not passing CREATE_NEW_CONSOLE has been known to
4076 cause random failures on win9x. Specifically a
4077 dialog:
4078 "Your program accessed mem currently in use at xxx"
4079 and a hopeful warning about the stability of your
4080 system.
4081 Cost is Ctrl+C wont kill children, but anyone
4082 who cares can have a go!
4083 */
4084 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004085 }
4086 }
4087
4088 /* Could be an else here to try cmd.exe / command.com in the path
4089 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004090 else {
Tim Peters402d5982001-08-27 06:37:48 +00004091 PyErr_SetString(PyExc_RuntimeError,
4092 "Cannot locate a COMSPEC environment variable to "
4093 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004094 return FALSE;
4095 }
Tim Peters5aa91602002-01-30 05:46:57 +00004096
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004097 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4098 siStartInfo.cb = sizeof(STARTUPINFO);
4099 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4100 siStartInfo.hStdInput = hStdin;
4101 siStartInfo.hStdOutput = hStdout;
4102 siStartInfo.hStdError = hStderr;
4103 siStartInfo.wShowWindow = SW_HIDE;
4104
4105 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004106 s2,
4107 NULL,
4108 NULL,
4109 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004110 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004111 NULL,
4112 NULL,
4113 &siStartInfo,
4114 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004115 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004116 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004117
Mark Hammondb37a3732000-08-14 04:47:33 +00004118 /* Return process handle */
4119 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004120 return TRUE;
4121 }
Tim Peters402d5982001-08-27 06:37:48 +00004122 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004123 return FALSE;
4124}
4125
4126/* The following code is based off of KB: Q190351 */
4127
4128static PyObject *
4129_PyPopen(char *cmdstring, int mode, int n)
4130{
4131 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4132 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004133 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004134
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004135 SECURITY_ATTRIBUTES saAttr;
4136 BOOL fSuccess;
4137 int fd1, fd2, fd3;
4138 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004139 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004140 PyObject *f;
4141
4142 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4143 saAttr.bInheritHandle = TRUE;
4144 saAttr.lpSecurityDescriptor = NULL;
4145
4146 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4147 return win32_error("CreatePipe", NULL);
4148
4149 /* Create new output read handle and the input write handle. Set
4150 * the inheritance properties to FALSE. Otherwise, the child inherits
4151 * the these handles; resulting in non-closeable handles to the pipes
4152 * being created. */
4153 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004154 GetCurrentProcess(), &hChildStdinWrDup, 0,
4155 FALSE,
4156 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004157 if (!fSuccess)
4158 return win32_error("DuplicateHandle", NULL);
4159
4160 /* Close the inheritable version of ChildStdin
4161 that we're using. */
4162 CloseHandle(hChildStdinWr);
4163
4164 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4165 return win32_error("CreatePipe", NULL);
4166
4167 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004168 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4169 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004170 if (!fSuccess)
4171 return win32_error("DuplicateHandle", NULL);
4172
4173 /* Close the inheritable version of ChildStdout
4174 that we're using. */
4175 CloseHandle(hChildStdoutRd);
4176
4177 if (n != POPEN_4) {
4178 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4179 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004180 fSuccess = DuplicateHandle(GetCurrentProcess(),
4181 hChildStderrRd,
4182 GetCurrentProcess(),
4183 &hChildStderrRdDup, 0,
4184 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004185 if (!fSuccess)
4186 return win32_error("DuplicateHandle", NULL);
4187 /* Close the inheritable version of ChildStdErr that we're using. */
4188 CloseHandle(hChildStderrRd);
4189 }
Tim Peters5aa91602002-01-30 05:46:57 +00004190
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004191 switch (n) {
4192 case POPEN_1:
4193 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4194 case _O_WRONLY | _O_TEXT:
4195 /* Case for writing to child Stdin in text mode. */
4196 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4197 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004198 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004199 PyFile_SetBufSize(f, 0);
4200 /* We don't care about these pipes anymore, so close them. */
4201 CloseHandle(hChildStdoutRdDup);
4202 CloseHandle(hChildStderrRdDup);
4203 break;
4204
4205 case _O_RDONLY | _O_TEXT:
4206 /* Case for reading from child Stdout in text mode. */
4207 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4208 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004209 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004210 PyFile_SetBufSize(f, 0);
4211 /* We don't care about these pipes anymore, so close them. */
4212 CloseHandle(hChildStdinWrDup);
4213 CloseHandle(hChildStderrRdDup);
4214 break;
4215
4216 case _O_RDONLY | _O_BINARY:
4217 /* Case for readinig from child Stdout in binary mode. */
4218 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4219 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004220 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004221 PyFile_SetBufSize(f, 0);
4222 /* We don't care about these pipes anymore, so close them. */
4223 CloseHandle(hChildStdinWrDup);
4224 CloseHandle(hChildStderrRdDup);
4225 break;
4226
4227 case _O_WRONLY | _O_BINARY:
4228 /* Case for writing to child Stdin in binary mode. */
4229 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4230 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004231 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004232 PyFile_SetBufSize(f, 0);
4233 /* We don't care about these pipes anymore, so close them. */
4234 CloseHandle(hChildStdoutRdDup);
4235 CloseHandle(hChildStderrRdDup);
4236 break;
4237 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004238 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004239 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004240
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004241 case POPEN_2:
4242 case POPEN_4:
4243 {
4244 char *m1, *m2;
4245 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004246
Tim Peters7dca21e2002-08-19 00:42:29 +00004247 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004248 m1 = "r";
4249 m2 = "w";
4250 } else {
4251 m1 = "rb";
4252 m2 = "wb";
4253 }
4254
4255 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4256 f1 = _fdopen(fd1, m2);
4257 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4258 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004259 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004260 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004261 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004262 PyFile_SetBufSize(p2, 0);
4263
4264 if (n != 4)
4265 CloseHandle(hChildStderrRdDup);
4266
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004267 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004268 Py_XDECREF(p1);
4269 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004270 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004271 break;
4272 }
Tim Peters5aa91602002-01-30 05:46:57 +00004273
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004274 case POPEN_3:
4275 {
4276 char *m1, *m2;
4277 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004278
Tim Peters7dca21e2002-08-19 00:42:29 +00004279 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004280 m1 = "r";
4281 m2 = "w";
4282 } else {
4283 m1 = "rb";
4284 m2 = "wb";
4285 }
4286
4287 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4288 f1 = _fdopen(fd1, m2);
4289 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4290 f2 = _fdopen(fd2, m1);
4291 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4292 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004293 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004294 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4295 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004296 PyFile_SetBufSize(p1, 0);
4297 PyFile_SetBufSize(p2, 0);
4298 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004299 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004300 Py_XDECREF(p1);
4301 Py_XDECREF(p2);
4302 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004303 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004304 break;
4305 }
4306 }
4307
4308 if (n == POPEN_4) {
4309 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004310 hChildStdinRd,
4311 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004312 hChildStdoutWr,
4313 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004314 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004315 }
4316 else {
4317 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004318 hChildStdinRd,
4319 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004320 hChildStderrWr,
4321 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004322 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004323 }
4324
Mark Hammondb37a3732000-08-14 04:47:33 +00004325 /*
4326 * Insert the files we've created into the process dictionary
4327 * all referencing the list with the process handle and the
4328 * initial number of files (see description below in _PyPclose).
4329 * Since if _PyPclose later tried to wait on a process when all
4330 * handles weren't closed, it could create a deadlock with the
4331 * child, we spend some energy here to try to ensure that we
4332 * either insert all file handles into the dictionary or none
4333 * at all. It's a little clumsy with the various popen modes
4334 * and variable number of files involved.
4335 */
4336 if (!_PyPopenProcs) {
4337 _PyPopenProcs = PyDict_New();
4338 }
4339
4340 if (_PyPopenProcs) {
4341 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4342 int ins_rc[3];
4343
4344 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4345 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4346
4347 procObj = PyList_New(2);
4348 hProcessObj = PyLong_FromVoidPtr(hProcess);
4349 intObj = PyInt_FromLong(file_count);
4350
4351 if (procObj && hProcessObj && intObj) {
4352 PyList_SetItem(procObj,0,hProcessObj);
4353 PyList_SetItem(procObj,1,intObj);
4354
4355 fileObj[0] = PyLong_FromVoidPtr(f1);
4356 if (fileObj[0]) {
4357 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4358 fileObj[0],
4359 procObj);
4360 }
4361 if (file_count >= 2) {
4362 fileObj[1] = PyLong_FromVoidPtr(f2);
4363 if (fileObj[1]) {
4364 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4365 fileObj[1],
4366 procObj);
4367 }
4368 }
4369 if (file_count >= 3) {
4370 fileObj[2] = PyLong_FromVoidPtr(f3);
4371 if (fileObj[2]) {
4372 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4373 fileObj[2],
4374 procObj);
4375 }
4376 }
4377
4378 if (ins_rc[0] < 0 || !fileObj[0] ||
4379 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4380 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4381 /* Something failed - remove any dictionary
4382 * entries that did make it.
4383 */
4384 if (!ins_rc[0] && fileObj[0]) {
4385 PyDict_DelItem(_PyPopenProcs,
4386 fileObj[0]);
4387 }
4388 if (!ins_rc[1] && fileObj[1]) {
4389 PyDict_DelItem(_PyPopenProcs,
4390 fileObj[1]);
4391 }
4392 if (!ins_rc[2] && fileObj[2]) {
4393 PyDict_DelItem(_PyPopenProcs,
4394 fileObj[2]);
4395 }
4396 }
4397 }
Tim Peters5aa91602002-01-30 05:46:57 +00004398
Mark Hammondb37a3732000-08-14 04:47:33 +00004399 /*
4400 * Clean up our localized references for the dictionary keys
4401 * and value since PyDict_SetItem will Py_INCREF any copies
4402 * that got placed in the dictionary.
4403 */
4404 Py_XDECREF(procObj);
4405 Py_XDECREF(fileObj[0]);
4406 Py_XDECREF(fileObj[1]);
4407 Py_XDECREF(fileObj[2]);
4408 }
4409
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004410 /* Child is launched. Close the parents copy of those pipe
4411 * handles that only the child should have open. You need to
4412 * make sure that no handles to the write end of the output pipe
4413 * are maintained in this process or else the pipe will not close
4414 * when the child process exits and the ReadFile will hang. */
4415
4416 if (!CloseHandle(hChildStdinRd))
4417 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004418
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004419 if (!CloseHandle(hChildStdoutWr))
4420 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004421
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004422 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4423 return win32_error("CloseHandle", NULL);
4424
4425 return f;
4426}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004427
4428/*
4429 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4430 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004431 *
4432 * This function uses the _PyPopenProcs dictionary in order to map the
4433 * input file pointer to information about the process that was
4434 * originally created by the popen* call that created the file pointer.
4435 * The dictionary uses the file pointer as a key (with one entry
4436 * inserted for each file returned by the original popen* call) and a
4437 * single list object as the value for all files from a single call.
4438 * The list object contains the Win32 process handle at [0], and a file
4439 * count at [1], which is initialized to the total number of file
4440 * handles using that list.
4441 *
4442 * This function closes whichever handle it is passed, and decrements
4443 * the file count in the dictionary for the process handle pointed to
4444 * by this file. On the last close (when the file count reaches zero),
4445 * this function will wait for the child process and then return its
4446 * exit code as the result of the close() operation. This permits the
4447 * files to be closed in any order - it is always the close() of the
4448 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004449 */
Tim Peters736aa322000-09-01 06:51:24 +00004450
4451 /* RED_FLAG 31-Aug-2000 Tim
4452 * This is always called (today!) between a pair of
4453 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4454 * macros. So the thread running this has no valid thread state, as
4455 * far as Python is concerned. However, this calls some Python API
4456 * functions that cannot be called safely without a valid thread
4457 * state, in particular PyDict_GetItem.
4458 * As a temporary hack (although it may last for years ...), we
4459 * *rely* on not having a valid thread state in this function, in
4460 * order to create our own "from scratch".
4461 * This will deadlock if _PyPclose is ever called by a thread
4462 * holding the global lock.
4463 */
4464
Fredrik Lundh56055a42000-07-23 19:47:12 +00004465static int _PyPclose(FILE *file)
4466{
Fredrik Lundh20318932000-07-26 17:29:12 +00004467 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004468 DWORD exit_code;
4469 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004470 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4471 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004472#ifdef WITH_THREAD
4473 PyInterpreterState* pInterpreterState;
4474 PyThreadState* pThreadState;
4475#endif
4476
Fredrik Lundh20318932000-07-26 17:29:12 +00004477 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004478 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004479 */
4480 result = fclose(file);
4481
Tim Peters736aa322000-09-01 06:51:24 +00004482#ifdef WITH_THREAD
4483 /* Bootstrap a valid thread state into existence. */
4484 pInterpreterState = PyInterpreterState_New();
4485 if (!pInterpreterState) {
4486 /* Well, we're hosed now! We don't have a thread
4487 * state, so can't call a nice error routine, or raise
4488 * an exception. Just die.
4489 */
4490 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004491 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004492 return -1; /* unreachable */
4493 }
4494 pThreadState = PyThreadState_New(pInterpreterState);
4495 if (!pThreadState) {
4496 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004497 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004498 return -1; /* unreachable */
4499 }
4500 /* Grab the global lock. Note that this will deadlock if the
4501 * current thread already has the lock! (see RED_FLAG comments
4502 * before this function)
4503 */
4504 PyEval_RestoreThread(pThreadState);
4505#endif
4506
Fredrik Lundh56055a42000-07-23 19:47:12 +00004507 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004508 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4509 (procObj = PyDict_GetItem(_PyPopenProcs,
4510 fileObj)) != NULL &&
4511 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4512 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4513
4514 hProcess = PyLong_AsVoidPtr(hProcessObj);
4515 file_count = PyInt_AsLong(intObj);
4516
4517 if (file_count > 1) {
4518 /* Still other files referencing process */
4519 file_count--;
4520 PyList_SetItem(procObj,1,
4521 PyInt_FromLong(file_count));
4522 } else {
4523 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004524 if (result != EOF &&
4525 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4526 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004527 /* Possible truncation here in 16-bit environments, but
4528 * real exit codes are just the lower byte in any event.
4529 */
4530 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004531 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004532 /* Indicate failure - this will cause the file object
4533 * to raise an I/O error and translate the last Win32
4534 * error code from errno. We do have a problem with
4535 * last errors that overlap the normal errno table,
4536 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004537 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004538 if (result != EOF) {
4539 /* If the error wasn't from the fclose(), then
4540 * set errno for the file object error handling.
4541 */
4542 errno = GetLastError();
4543 }
4544 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004545 }
4546
4547 /* Free up the native handle at this point */
4548 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004549 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004550
Mark Hammondb37a3732000-08-14 04:47:33 +00004551 /* Remove this file pointer from dictionary */
4552 PyDict_DelItem(_PyPopenProcs, fileObj);
4553
4554 if (PyDict_Size(_PyPopenProcs) == 0) {
4555 Py_DECREF(_PyPopenProcs);
4556 _PyPopenProcs = NULL;
4557 }
4558
4559 } /* if object retrieval ok */
4560
4561 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004562 } /* if _PyPopenProcs */
4563
Tim Peters736aa322000-09-01 06:51:24 +00004564#ifdef WITH_THREAD
4565 /* Tear down the thread & interpreter states.
4566 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004567 * call the thread clear & delete functions, and indeed insist on
4568 * doing that themselves. The lock must be held during the clear, but
4569 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004570 */
4571 PyInterpreterState_Clear(pInterpreterState);
4572 PyEval_ReleaseThread(pThreadState);
4573 PyInterpreterState_Delete(pInterpreterState);
4574#endif
4575
Fredrik Lundh56055a42000-07-23 19:47:12 +00004576 return result;
4577}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004578
4579#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004581posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004582{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004583 char *name;
4584 char *mode = "r";
4585 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004586 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004588 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004589 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004590 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004591 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004592 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004593 if (fp == NULL)
4594 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004595 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004596 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004597 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004598 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004599}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004600
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004601#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004602#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004604
Guido van Rossumb6775db1994-08-01 11:34:53 +00004605#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004607"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608Set the current process's user id.");
4609
Barry Warsaw53699e91996-12-10 23:23:01 +00004610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004611posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004612{
4613 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004614 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004615 return NULL;
4616 if (setuid(uid) < 0)
4617 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004618 Py_INCREF(Py_None);
4619 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004620}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004621#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004623
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004624#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004625PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004626"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004627Set the current process's effective user id.");
4628
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004629static PyObject *
4630posix_seteuid (PyObject *self, PyObject *args)
4631{
4632 int euid;
4633 if (!PyArg_ParseTuple(args, "i", &euid)) {
4634 return NULL;
4635 } else if (seteuid(euid) < 0) {
4636 return posix_error();
4637 } else {
4638 Py_INCREF(Py_None);
4639 return Py_None;
4640 }
4641}
4642#endif /* HAVE_SETEUID */
4643
4644#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004645PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004646"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004647Set the current process's effective group id.");
4648
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004649static PyObject *
4650posix_setegid (PyObject *self, PyObject *args)
4651{
4652 int egid;
4653 if (!PyArg_ParseTuple(args, "i", &egid)) {
4654 return NULL;
4655 } else if (setegid(egid) < 0) {
4656 return posix_error();
4657 } else {
4658 Py_INCREF(Py_None);
4659 return Py_None;
4660 }
4661}
4662#endif /* HAVE_SETEGID */
4663
4664#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004665PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004666"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004667Set the current process's real and effective user ids.");
4668
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004669static PyObject *
4670posix_setreuid (PyObject *self, PyObject *args)
4671{
4672 int ruid, euid;
4673 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4674 return NULL;
4675 } else if (setreuid(ruid, euid) < 0) {
4676 return posix_error();
4677 } else {
4678 Py_INCREF(Py_None);
4679 return Py_None;
4680 }
4681}
4682#endif /* HAVE_SETREUID */
4683
4684#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004686"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004687Set the current process's real and effective group ids.");
4688
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004689static PyObject *
4690posix_setregid (PyObject *self, PyObject *args)
4691{
4692 int rgid, egid;
4693 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4694 return NULL;
4695 } else if (setregid(rgid, egid) < 0) {
4696 return posix_error();
4697 } else {
4698 Py_INCREF(Py_None);
4699 return Py_None;
4700 }
4701}
4702#endif /* HAVE_SETREGID */
4703
Guido van Rossumb6775db1994-08-01 11:34:53 +00004704#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004706"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004707Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004708
Barry Warsaw53699e91996-12-10 23:23:01 +00004709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004710posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004711{
4712 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004713 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004714 return NULL;
4715 if (setgid(gid) < 0)
4716 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004717 Py_INCREF(Py_None);
4718 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004719}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004720#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004721
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004722#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004723PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004724"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004725Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004726
4727static PyObject *
4728posix_setgroups(PyObject *self, PyObject *args)
4729{
4730 PyObject *groups;
4731 int i, len;
4732 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004733
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004734 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4735 return NULL;
4736 if (!PySequence_Check(groups)) {
4737 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4738 return NULL;
4739 }
4740 len = PySequence_Size(groups);
4741 if (len > MAX_GROUPS) {
4742 PyErr_SetString(PyExc_ValueError, "too many groups");
4743 return NULL;
4744 }
4745 for(i = 0; i < len; i++) {
4746 PyObject *elem;
4747 elem = PySequence_GetItem(groups, i);
4748 if (!elem)
4749 return NULL;
4750 if (!PyInt_Check(elem)) {
4751 PyErr_SetString(PyExc_TypeError,
4752 "groups must be integers");
4753 Py_DECREF(elem);
4754 return NULL;
4755 }
4756 /* XXX: check that value fits into gid_t. */
4757 grouplist[i] = PyInt_AsLong(elem);
4758 Py_DECREF(elem);
4759 }
4760
4761 if (setgroups(len, grouplist) < 0)
4762 return posix_error();
4763 Py_INCREF(Py_None);
4764 return Py_None;
4765}
4766#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004767
Guido van Rossumb6775db1994-08-01 11:34:53 +00004768#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004769PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004770"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004771Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004772
Barry Warsaw53699e91996-12-10 23:23:01 +00004773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004774posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004775{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004776 int pid, options;
4777#ifdef UNION_WAIT
4778 union wait status;
4779#define status_i (status.w_status)
4780#else
4781 int status;
4782#define status_i status
4783#endif
4784 status_i = 0;
4785
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004786 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004787 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004788 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004789 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004790 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004791 if (pid == -1)
4792 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004793 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004794 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004795}
4796
Tim Petersab034fa2002-02-01 11:27:43 +00004797#elif defined(HAVE_CWAIT)
4798
4799/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004800PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004801"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004802"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004803
4804static PyObject *
4805posix_waitpid(PyObject *self, PyObject *args)
4806{
4807 int pid, options;
4808 int status;
4809
4810 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4811 return NULL;
4812 Py_BEGIN_ALLOW_THREADS
4813 pid = _cwait(&status, pid, options);
4814 Py_END_ALLOW_THREADS
4815 if (pid == -1)
4816 return posix_error();
4817 else
4818 /* shift the status left a byte so this is more like the
4819 POSIX waitpid */
4820 return Py_BuildValue("ii", pid, status << 8);
4821}
4822#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004823
Guido van Rossumad0ee831995-03-01 10:34:45 +00004824#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004825PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004826"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004828
Barry Warsaw53699e91996-12-10 23:23:01 +00004829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004830posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004831{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004832 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004833#ifdef UNION_WAIT
4834 union wait status;
4835#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004836#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004837 int status;
4838#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004839#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004840 if (!PyArg_ParseTuple(args, ":wait"))
4841 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004842 status_i = 0;
4843 Py_BEGIN_ALLOW_THREADS
4844 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004845 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004846 if (pid == -1)
4847 return posix_error();
4848 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004849 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004850#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004851}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004852#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004854
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004855PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004856"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004857Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004858
Barry Warsaw53699e91996-12-10 23:23:01 +00004859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004860posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004861{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004862#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004863 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004864#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004865#ifdef MS_WINDOWS
4866 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4867#else
4868 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4869#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004870#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004871}
4872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004873
Guido van Rossumb6775db1994-08-01 11:34:53 +00004874#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004875PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004876"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004877Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004878
Barry Warsaw53699e91996-12-10 23:23:01 +00004879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004880posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004881{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004882 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004883 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004884 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004885 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004886 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004887 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004888 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004889 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004890 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004891 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004892 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004893}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004894#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004896
Guido van Rossumb6775db1994-08-01 11:34:53 +00004897#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004898PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004899"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004900Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004901
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004903posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004904{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004905 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004906}
4907#endif /* HAVE_SYMLINK */
4908
4909
4910#ifdef HAVE_TIMES
4911#ifndef HZ
4912#define HZ 60 /* Universal constant :-) */
4913#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004914
Guido van Rossumd48f2521997-12-05 22:19:34 +00004915#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4916static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004917system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004918{
4919 ULONG value = 0;
4920
4921 Py_BEGIN_ALLOW_THREADS
4922 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4923 Py_END_ALLOW_THREADS
4924
4925 return value;
4926}
4927
4928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004929posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004930{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004932 return NULL;
4933
4934 /* Currently Only Uptime is Provided -- Others Later */
4935 return Py_BuildValue("ddddd",
4936 (double)0 /* t.tms_utime / HZ */,
4937 (double)0 /* t.tms_stime / HZ */,
4938 (double)0 /* t.tms_cutime / HZ */,
4939 (double)0 /* t.tms_cstime / HZ */,
4940 (double)system_uptime() / 1000);
4941}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004942#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004944posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004945{
4946 struct tms t;
4947 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004948 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004949 return NULL;
4950 errno = 0;
4951 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004952 if (c == (clock_t) -1)
4953 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004954 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004955 (double)t.tms_utime / HZ,
4956 (double)t.tms_stime / HZ,
4957 (double)t.tms_cutime / HZ,
4958 (double)t.tms_cstime / HZ,
4959 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004960}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004961#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004962#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004963
4964
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004965#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004966#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004968posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004969{
4970 FILETIME create, exit, kernel, user;
4971 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004973 return NULL;
4974 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004975 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4976 /* The fields of a FILETIME structure are the hi and lo part
4977 of a 64-bit value expressed in 100 nanosecond units.
4978 1e7 is one second in such units; 1e-7 the inverse.
4979 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4980 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 return Py_BuildValue(
4982 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004983 (double)(kernel.dwHighDateTime*429.4967296 +
4984 kernel.dwLowDateTime*1e-7),
4985 (double)(user.dwHighDateTime*429.4967296 +
4986 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004987 (double)0,
4988 (double)0,
4989 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004990}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004991#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004992
4993#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004995"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004997#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004999
Guido van Rossumb6775db1994-08-01 11:34:53 +00005000#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005002"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Barry Warsaw53699e91996-12-10 23:23:01 +00005005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005006posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005007{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005008 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005009 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005010 if (setsid() < 0)
5011 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005012 Py_INCREF(Py_None);
5013 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005014}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005015#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005016
Guido van Rossumb6775db1994-08-01 11:34:53 +00005017#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005018PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005019"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005020Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005021
Barry Warsaw53699e91996-12-10 23:23:01 +00005022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005023posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005024{
5025 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005026 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005027 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005028 if (setpgid(pid, pgrp) < 0)
5029 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005030 Py_INCREF(Py_None);
5031 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005032}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005033#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Guido van Rossumb6775db1994-08-01 11:34:53 +00005036#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005038"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005039Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005040
Barry Warsaw53699e91996-12-10 23:23:01 +00005041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005042posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005043{
5044 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005045 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005046 return NULL;
5047 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005048 if (pgid < 0)
5049 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005050 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005051}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005052#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Guido van Rossumb6775db1994-08-01 11:34:53 +00005055#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005057"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Barry Warsaw53699e91996-12-10 23:23:01 +00005060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005061posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005062{
5063 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005064 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005065 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005066 if (tcsetpgrp(fd, pgid) < 0)
5067 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005068 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005069 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005070}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005071#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005072
Guido van Rossum687dd131993-05-17 08:34:16 +00005073/* Functions acting on file descriptors */
5074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Barry Warsaw53699e91996-12-10 23:23:01 +00005079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005080posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005081{
Mark Hammondef8b6542001-05-13 08:04:26 +00005082 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005083 int flag;
5084 int mode = 0777;
5085 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005086
5087#ifdef MS_WINDOWS
5088 if (unicode_file_names()) {
5089 PyUnicodeObject *po;
5090 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5091 Py_BEGIN_ALLOW_THREADS
5092 /* PyUnicode_AS_UNICODE OK without thread
5093 lock as it is a simple dereference. */
5094 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5095 Py_END_ALLOW_THREADS
5096 if (fd < 0)
5097 return posix_error();
5098 return PyInt_FromLong((long)fd);
5099 }
5100 /* Drop the argument parsing error as narrow strings
5101 are also valid. */
5102 PyErr_Clear();
5103 }
5104#endif
5105
Tim Peters5aa91602002-01-30 05:46:57 +00005106 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005107 Py_FileSystemDefaultEncoding, &file,
5108 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005109 return NULL;
5110
Barry Warsaw53699e91996-12-10 23:23:01 +00005111 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005112 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005113 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005114 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005115 return posix_error_with_allocated_filename(file);
5116 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005117 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005118}
5119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005121PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005122"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005124
Barry Warsaw53699e91996-12-10 23:23:01 +00005125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005126posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005127{
5128 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005129 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005130 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005131 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005132 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005133 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005134 if (res < 0)
5135 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005136 Py_INCREF(Py_None);
5137 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005138}
5139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005140
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005142"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005143Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Barry Warsaw53699e91996-12-10 23:23:01 +00005145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005146posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005147{
5148 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005150 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005151 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005152 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005153 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005154 if (fd < 0)
5155 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005156 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005157}
5158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005160PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005161"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005162Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005163
Barry Warsaw53699e91996-12-10 23:23:01 +00005164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005165posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005166{
5167 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005168 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005170 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005171 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005172 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005173 if (res < 0)
5174 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005175 Py_INCREF(Py_None);
5176 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005177}
5178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005181"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005182Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005183
Barry Warsaw53699e91996-12-10 23:23:01 +00005184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005185posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005186{
5187 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005188#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005189 LONG_LONG pos, res;
5190#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005191 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005192#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005193 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005194 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005195 return NULL;
5196#ifdef SEEK_SET
5197 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5198 switch (how) {
5199 case 0: how = SEEK_SET; break;
5200 case 1: how = SEEK_CUR; break;
5201 case 2: how = SEEK_END; break;
5202 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005203#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005204
5205#if !defined(HAVE_LARGEFILE_SUPPORT)
5206 pos = PyInt_AsLong(posobj);
5207#else
5208 pos = PyLong_Check(posobj) ?
5209 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5210#endif
5211 if (PyErr_Occurred())
5212 return NULL;
5213
Barry Warsaw53699e91996-12-10 23:23:01 +00005214 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005215#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005216 res = _lseeki64(fd, pos, how);
5217#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005218 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005219#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005220 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005221 if (res < 0)
5222 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005223
5224#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005225 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005226#else
5227 return PyLong_FromLongLong(res);
5228#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005229}
5230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005233"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005234Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005235
Barry Warsaw53699e91996-12-10 23:23:01 +00005236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005237posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005238{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005239 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005240 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005242 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005243 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005244 if (buffer == NULL)
5245 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005246 Py_BEGIN_ALLOW_THREADS
5247 n = read(fd, PyString_AsString(buffer), size);
5248 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005249 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005250 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005251 return posix_error();
5252 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005253 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005254 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005255 return buffer;
5256}
5257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005260"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005261Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005262
Barry Warsaw53699e91996-12-10 23:23:01 +00005263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005264posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005265{
5266 int fd, size;
5267 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005268 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005269 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005270 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005271 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005272 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005273 if (size < 0)
5274 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005275 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005276}
5277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005279PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005280"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005281Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005282
Barry Warsaw53699e91996-12-10 23:23:01 +00005283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005284posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005285{
5286 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005287 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005288 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005289 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005290 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005291 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005292 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005293 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005294 if (res != 0)
5295 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005296
Fred Drake699f3522000-06-29 21:12:41 +00005297 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005298}
5299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005301PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005302"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005303Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005304
Barry Warsaw53699e91996-12-10 23:23:01 +00005305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005306posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005307{
Guido van Rossum687dd131993-05-17 08:34:16 +00005308 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005309 char *mode = "r";
5310 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005311 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005312 PyObject *f;
5313 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005314 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005315
Thomas Heller1f043e22002-11-07 16:00:59 +00005316 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5317 PyErr_Format(PyExc_ValueError,
5318 "invalid file mode '%s'", mode);
5319 return NULL;
5320 }
5321
Barry Warsaw53699e91996-12-10 23:23:01 +00005322 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005323 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005324 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005325 if (fp == NULL)
5326 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005327 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005328 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005329 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005330 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005331}
5332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005334"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005335Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005336connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005337
5338static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005339posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005340{
5341 int fd;
5342 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5343 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005344 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005345}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005346
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005347#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005348PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005349"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005351
Barry Warsaw53699e91996-12-10 23:23:01 +00005352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005353posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005354{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005355#if defined(PYOS_OS2)
5356 HFILE read, write;
5357 APIRET rc;
5358
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005360 return NULL;
5361
5362 Py_BEGIN_ALLOW_THREADS
5363 rc = DosCreatePipe( &read, &write, 4096);
5364 Py_END_ALLOW_THREADS
5365 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005366 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005367
5368 return Py_BuildValue("(ii)", read, write);
5369#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005370#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 int fds[2];
5372 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005373 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005374 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005375 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005376#if defined(__VMS)
5377 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5378#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005379 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005380#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005381 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005382 if (res != 0)
5383 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005384 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005385#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005386 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005387 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005388 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005390 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005391 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005392 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005393 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005394 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005395 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005396 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5397 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005398 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005399#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005400#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005401}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005402#endif /* HAVE_PIPE */
5403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005405#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005406PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005407"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005408Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005409
Barry Warsaw53699e91996-12-10 23:23:01 +00005410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005411posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005412{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005413 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005414 int mode = 0666;
5415 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005416 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005417 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005418 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005419 res = mkfifo(filename, mode);
5420 Py_END_ALLOW_THREADS
5421 if (res < 0)
5422 return posix_error();
5423 Py_INCREF(Py_None);
5424 return Py_None;
5425}
5426#endif
5427
5428
Neal Norwitz11690112002-07-30 01:08:28 +00005429#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005430PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005431"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005432Create a filesystem node (file, device special file or named pipe)\n\
5433named filename. mode specifies both the permissions to use and the\n\
5434type of node to be created, being combined (bitwise OR) with one of\n\
5435S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005436device defines the newly created device special file (probably using\n\
5437os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005438
5439
5440static PyObject *
5441posix_mknod(PyObject *self, PyObject *args)
5442{
5443 char *filename;
5444 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005445 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005446 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005447 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005448 return NULL;
5449 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005450 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005451 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005452 if (res < 0)
5453 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005454 Py_INCREF(Py_None);
5455 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005456}
5457#endif
5458
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005459#ifdef HAVE_DEVICE_MACROS
5460PyDoc_STRVAR(posix_major__doc__,
5461"major(device) -> major number\n\
5462Extracts a device major number from a raw device number.");
5463
5464static PyObject *
5465posix_major(PyObject *self, PyObject *args)
5466{
5467 int device;
5468 if (!PyArg_ParseTuple(args, "i:major", &device))
5469 return NULL;
5470 return PyInt_FromLong((long)major(device));
5471}
5472
5473PyDoc_STRVAR(posix_minor__doc__,
5474"minor(device) -> minor number\n\
5475Extracts a device minor number from a raw device number.");
5476
5477static PyObject *
5478posix_minor(PyObject *self, PyObject *args)
5479{
5480 int device;
5481 if (!PyArg_ParseTuple(args, "i:minor", &device))
5482 return NULL;
5483 return PyInt_FromLong((long)minor(device));
5484}
5485
5486PyDoc_STRVAR(posix_makedev__doc__,
5487"makedev(major, minor) -> device number\n\
5488Composes a raw device number from the major and minor device numbers.");
5489
5490static PyObject *
5491posix_makedev(PyObject *self, PyObject *args)
5492{
5493 int major, minor;
5494 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5495 return NULL;
5496 return PyInt_FromLong((long)makedev(major, minor));
5497}
5498#endif /* device macros */
5499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005501#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Barry Warsaw53699e91996-12-10 23:23:01 +00005506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005507posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005508{
5509 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005510 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005511 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005512 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005513
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005514 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005515 return NULL;
5516
5517#if !defined(HAVE_LARGEFILE_SUPPORT)
5518 length = PyInt_AsLong(lenobj);
5519#else
5520 length = PyLong_Check(lenobj) ?
5521 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5522#endif
5523 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005524 return NULL;
5525
Barry Warsaw53699e91996-12-10 23:23:01 +00005526 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005527 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005528 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005529 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005530 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005531 return NULL;
5532 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005533 Py_INCREF(Py_None);
5534 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005535}
5536#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005537
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005538#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005542
Fred Drake762e2061999-08-26 17:23:54 +00005543/* Save putenv() parameters as values here, so we can collect them when they
5544 * get re-set with another call for the same key. */
5545static PyObject *posix_putenv_garbage;
5546
Tim Peters5aa91602002-01-30 05:46:57 +00005547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005548posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005549{
5550 char *s1, *s2;
5551 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005552 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005553 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005554
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005555 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005556 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005557
5558#if defined(PYOS_OS2)
5559 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5560 APIRET rc;
5561
5562 if (strlen(s2) == 0) /* If New Value is an Empty String */
5563 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5564
5565 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5566 if (rc != NO_ERROR)
5567 return os2_error(rc);
5568
5569 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5570 APIRET rc;
5571
5572 if (strlen(s2) == 0) /* If New Value is an Empty String */
5573 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5574
5575 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5576 if (rc != NO_ERROR)
5577 return os2_error(rc);
5578 } else {
5579#endif
5580
Fred Drake762e2061999-08-26 17:23:54 +00005581 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005582 len = strlen(s1) + strlen(s2) + 2;
5583 /* len includes space for a trailing \0; the size arg to
5584 PyString_FromStringAndSize does not count that */
5585 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005586 if (newstr == NULL)
5587 return PyErr_NoMemory();
5588 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005589 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005590 if (putenv(new)) {
5591 posix_error();
5592 return NULL;
5593 }
Fred Drake762e2061999-08-26 17:23:54 +00005594 /* Install the first arg and newstr in posix_putenv_garbage;
5595 * this will cause previous value to be collected. This has to
5596 * happen after the real putenv() call because the old value
5597 * was still accessible until then. */
5598 if (PyDict_SetItem(posix_putenv_garbage,
5599 PyTuple_GET_ITEM(args, 0), newstr)) {
5600 /* really not much we can do; just leak */
5601 PyErr_Clear();
5602 }
5603 else {
5604 Py_DECREF(newstr);
5605 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005606
5607#if defined(PYOS_OS2)
5608 }
5609#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005610 Py_INCREF(Py_None);
5611 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005612}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005613#endif /* putenv */
5614
Guido van Rossumc524d952001-10-19 01:31:59 +00005615#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005616PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005617"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005618Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005619
5620static PyObject *
5621posix_unsetenv(PyObject *self, PyObject *args)
5622{
5623 char *s1;
5624
5625 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5626 return NULL;
5627
5628 unsetenv(s1);
5629
5630 /* Remove the key from posix_putenv_garbage;
5631 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005632 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005633 * old value was still accessible until then.
5634 */
5635 if (PyDict_DelItem(posix_putenv_garbage,
5636 PyTuple_GET_ITEM(args, 0))) {
5637 /* really not much we can do; just leak */
5638 PyErr_Clear();
5639 }
5640
5641 Py_INCREF(Py_None);
5642 return Py_None;
5643}
5644#endif /* unsetenv */
5645
Guido van Rossumb6a47161997-09-15 22:54:34 +00005646#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005648"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005650
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005652posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005653{
5654 int code;
5655 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005657 return NULL;
5658 message = strerror(code);
5659 if (message == NULL) {
5660 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005661 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005662 return NULL;
5663 }
5664 return PyString_FromString(message);
5665}
5666#endif /* strerror */
5667
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005668
Guido van Rossumc9641791998-08-04 15:26:23 +00005669#ifdef HAVE_SYS_WAIT_H
5670
Fred Drake106c1a02002-04-23 15:58:02 +00005671#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005673"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005675
5676static PyObject *
5677posix_WCOREDUMP(PyObject *self, PyObject *args)
5678{
5679#ifdef UNION_WAIT
5680 union wait status;
5681#define status_i (status.w_status)
5682#else
5683 int status;
5684#define status_i status
5685#endif
5686 status_i = 0;
5687
5688 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5689 {
5690 return NULL;
5691 }
5692
5693 return PyBool_FromLong(WCOREDUMP(status));
5694#undef status_i
5695}
5696#endif /* WCOREDUMP */
5697
5698#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005699PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005700"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005701Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005703
5704static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005705posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005706{
5707#ifdef UNION_WAIT
5708 union wait status;
5709#define status_i (status.w_status)
5710#else
5711 int status;
5712#define status_i status
5713#endif
5714 status_i = 0;
5715
5716 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5717 {
5718 return NULL;
5719 }
5720
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005721 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005722#undef status_i
5723}
5724#endif /* WIFCONTINUED */
5725
Guido van Rossumc9641791998-08-04 15:26:23 +00005726#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005728"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005730
5731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005732posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005733{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005734#ifdef UNION_WAIT
5735 union wait status;
5736#define status_i (status.w_status)
5737#else
5738 int status;
5739#define status_i status
5740#endif
5741 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005742
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005743 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005744 {
5745 return NULL;
5746 }
Tim Peters5aa91602002-01-30 05:46:57 +00005747
Fred Drake106c1a02002-04-23 15:58:02 +00005748 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005749#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005750}
5751#endif /* WIFSTOPPED */
5752
5753#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005754PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005755"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005756Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005757
5758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005759posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005760{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005761#ifdef UNION_WAIT
5762 union wait status;
5763#define status_i (status.w_status)
5764#else
5765 int status;
5766#define status_i status
5767#endif
5768 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005770 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005771 {
5772 return NULL;
5773 }
Tim Peters5aa91602002-01-30 05:46:57 +00005774
Fred Drake106c1a02002-04-23 15:58:02 +00005775 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005776#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005777}
5778#endif /* WIFSIGNALED */
5779
5780#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005781PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005782"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005783Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005785
5786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005787posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005788{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005789#ifdef UNION_WAIT
5790 union wait status;
5791#define status_i (status.w_status)
5792#else
5793 int status;
5794#define status_i status
5795#endif
5796 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005797
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005798 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005799 {
5800 return NULL;
5801 }
Tim Peters5aa91602002-01-30 05:46:57 +00005802
Fred Drake106c1a02002-04-23 15:58:02 +00005803 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005804#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005805}
5806#endif /* WIFEXITED */
5807
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005808#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005810"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005811Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005812
5813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005814posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005815{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005816#ifdef UNION_WAIT
5817 union wait status;
5818#define status_i (status.w_status)
5819#else
5820 int status;
5821#define status_i status
5822#endif
5823 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005824
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005825 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005826 {
5827 return NULL;
5828 }
Tim Peters5aa91602002-01-30 05:46:57 +00005829
Guido van Rossumc9641791998-08-04 15:26:23 +00005830 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005831#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005832}
5833#endif /* WEXITSTATUS */
5834
5835#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005836PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005837"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005838Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005840
5841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005842posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005843{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005844#ifdef UNION_WAIT
5845 union wait status;
5846#define status_i (status.w_status)
5847#else
5848 int status;
5849#define status_i status
5850#endif
5851 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005852
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005853 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005854 {
5855 return NULL;
5856 }
Tim Peters5aa91602002-01-30 05:46:57 +00005857
Guido van Rossumc9641791998-08-04 15:26:23 +00005858 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005859#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005860}
5861#endif /* WTERMSIG */
5862
5863#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005865"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005866Return the signal that stopped the process that provided\n\
5867the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005868
5869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005870posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005871{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005872#ifdef UNION_WAIT
5873 union wait status;
5874#define status_i (status.w_status)
5875#else
5876 int status;
5877#define status_i status
5878#endif
5879 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005880
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005881 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005882 {
5883 return NULL;
5884 }
Tim Peters5aa91602002-01-30 05:46:57 +00005885
Guido van Rossumc9641791998-08-04 15:26:23 +00005886 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005887#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005888}
5889#endif /* WSTOPSIG */
5890
5891#endif /* HAVE_SYS_WAIT_H */
5892
5893
Guido van Rossum94f6f721999-01-06 18:42:14 +00005894#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005895#ifdef _SCO_DS
5896/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5897 needed definitions in sys/statvfs.h */
5898#define _SVID3
5899#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005900#include <sys/statvfs.h>
5901
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005902static PyObject*
5903_pystatvfs_fromstructstatvfs(struct statvfs st) {
5904 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5905 if (v == NULL)
5906 return NULL;
5907
5908#if !defined(HAVE_LARGEFILE_SUPPORT)
5909 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5910 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5911 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5912 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5913 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5914 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5915 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5916 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5917 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5918 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5919#else
5920 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5921 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005922 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005923 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005924 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005925 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5926 PyStructSequence_SET_ITEM(v, 4,
5927 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005928 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005929 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005930 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005931 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005932 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005933 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5934 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5935 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5936#endif
5937
5938 return v;
5939}
5940
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005942"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005944
5945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005947{
5948 int fd, res;
5949 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005950
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005951 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005952 return NULL;
5953 Py_BEGIN_ALLOW_THREADS
5954 res = fstatvfs(fd, &st);
5955 Py_END_ALLOW_THREADS
5956 if (res != 0)
5957 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005958
5959 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005960}
5961#endif /* HAVE_FSTATVFS */
5962
5963
5964#if defined(HAVE_STATVFS)
5965#include <sys/statvfs.h>
5966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005967PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005968"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005969Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005970
5971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005972posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005973{
5974 char *path;
5975 int res;
5976 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005977 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005978 return NULL;
5979 Py_BEGIN_ALLOW_THREADS
5980 res = statvfs(path, &st);
5981 Py_END_ALLOW_THREADS
5982 if (res != 0)
5983 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005984
5985 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005986}
5987#endif /* HAVE_STATVFS */
5988
5989
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005990#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005993Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005994The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005996
5997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005998posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005999{
6000 PyObject *result = NULL;
6001 char *dir = NULL;
6002 char *pfx = NULL;
6003 char *name;
6004
6005 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6006 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006007
6008 if (PyErr_Warn(PyExc_RuntimeWarning,
6009 "tempnam is a potential security risk to your program") < 0)
6010 return NULL;
6011
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006012#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006013 name = _tempnam(dir, pfx);
6014#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006015 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006016#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006017 if (name == NULL)
6018 return PyErr_NoMemory();
6019 result = PyString_FromString(name);
6020 free(name);
6021 return result;
6022}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006023#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006024
6025
6026#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006027PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006028"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006030
6031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006032posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006033{
6034 FILE *fp;
6035
6036 if (!PyArg_ParseTuple(args, ":tmpfile"))
6037 return NULL;
6038 fp = tmpfile();
6039 if (fp == NULL)
6040 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006041 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006042}
6043#endif
6044
6045
6046#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006050
6051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006052posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006053{
6054 char buffer[L_tmpnam];
6055 char *name;
6056
6057 if (!PyArg_ParseTuple(args, ":tmpnam"))
6058 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006059
6060 if (PyErr_Warn(PyExc_RuntimeWarning,
6061 "tmpnam is a potential security risk to your program") < 0)
6062 return NULL;
6063
Greg Wardb48bc172000-03-01 21:51:56 +00006064#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006065 name = tmpnam_r(buffer);
6066#else
6067 name = tmpnam(buffer);
6068#endif
6069 if (name == NULL) {
6070 PyErr_SetObject(PyExc_OSError,
6071 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006072#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006073 "unexpected NULL from tmpnam_r"
6074#else
6075 "unexpected NULL from tmpnam"
6076#endif
6077 ));
6078 return NULL;
6079 }
6080 return PyString_FromString(buffer);
6081}
6082#endif
6083
6084
Fred Drakec9680921999-12-13 16:37:25 +00006085/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6086 * It maps strings representing configuration variable names to
6087 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006088 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006089 * rarely-used constants. There are three separate tables that use
6090 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006091 *
6092 * This code is always included, even if none of the interfaces that
6093 * need it are included. The #if hackery needed to avoid it would be
6094 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006095 */
6096struct constdef {
6097 char *name;
6098 long value;
6099};
6100
Fred Drake12c6e2d1999-12-14 21:25:03 +00006101static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006102conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6103 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006104{
6105 if (PyInt_Check(arg)) {
6106 *valuep = PyInt_AS_LONG(arg);
6107 return 1;
6108 }
6109 if (PyString_Check(arg)) {
6110 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006111 size_t lo = 0;
6112 size_t mid;
6113 size_t hi = tablesize;
6114 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006115 char *confname = PyString_AS_STRING(arg);
6116 while (lo < hi) {
6117 mid = (lo + hi) / 2;
6118 cmp = strcmp(confname, table[mid].name);
6119 if (cmp < 0)
6120 hi = mid;
6121 else if (cmp > 0)
6122 lo = mid + 1;
6123 else {
6124 *valuep = table[mid].value;
6125 return 1;
6126 }
6127 }
6128 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6129 }
6130 else
6131 PyErr_SetString(PyExc_TypeError,
6132 "configuration names must be strings or integers");
6133 return 0;
6134}
6135
6136
6137#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6138static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006139#ifdef _PC_ABI_AIO_XFER_MAX
6140 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6141#endif
6142#ifdef _PC_ABI_ASYNC_IO
6143 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6144#endif
Fred Drakec9680921999-12-13 16:37:25 +00006145#ifdef _PC_ASYNC_IO
6146 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6147#endif
6148#ifdef _PC_CHOWN_RESTRICTED
6149 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6150#endif
6151#ifdef _PC_FILESIZEBITS
6152 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6153#endif
6154#ifdef _PC_LAST
6155 {"PC_LAST", _PC_LAST},
6156#endif
6157#ifdef _PC_LINK_MAX
6158 {"PC_LINK_MAX", _PC_LINK_MAX},
6159#endif
6160#ifdef _PC_MAX_CANON
6161 {"PC_MAX_CANON", _PC_MAX_CANON},
6162#endif
6163#ifdef _PC_MAX_INPUT
6164 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6165#endif
6166#ifdef _PC_NAME_MAX
6167 {"PC_NAME_MAX", _PC_NAME_MAX},
6168#endif
6169#ifdef _PC_NO_TRUNC
6170 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6171#endif
6172#ifdef _PC_PATH_MAX
6173 {"PC_PATH_MAX", _PC_PATH_MAX},
6174#endif
6175#ifdef _PC_PIPE_BUF
6176 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6177#endif
6178#ifdef _PC_PRIO_IO
6179 {"PC_PRIO_IO", _PC_PRIO_IO},
6180#endif
6181#ifdef _PC_SOCK_MAXBUF
6182 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6183#endif
6184#ifdef _PC_SYNC_IO
6185 {"PC_SYNC_IO", _PC_SYNC_IO},
6186#endif
6187#ifdef _PC_VDISABLE
6188 {"PC_VDISABLE", _PC_VDISABLE},
6189#endif
6190};
6191
Fred Drakec9680921999-12-13 16:37:25 +00006192static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006193conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006194{
6195 return conv_confname(arg, valuep, posix_constants_pathconf,
6196 sizeof(posix_constants_pathconf)
6197 / sizeof(struct constdef));
6198}
6199#endif
6200
6201#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006203"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006204Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006205If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006206
6207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006208posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006209{
6210 PyObject *result = NULL;
6211 int name, fd;
6212
Fred Drake12c6e2d1999-12-14 21:25:03 +00006213 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6214 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006215 long limit;
6216
6217 errno = 0;
6218 limit = fpathconf(fd, name);
6219 if (limit == -1 && errno != 0)
6220 posix_error();
6221 else
6222 result = PyInt_FromLong(limit);
6223 }
6224 return result;
6225}
6226#endif
6227
6228
6229#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006231"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006232Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006234
6235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006236posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006237{
6238 PyObject *result = NULL;
6239 int name;
6240 char *path;
6241
6242 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6243 conv_path_confname, &name)) {
6244 long limit;
6245
6246 errno = 0;
6247 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006248 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006249 if (errno == EINVAL)
6250 /* could be a path or name problem */
6251 posix_error();
6252 else
6253 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006254 }
Fred Drakec9680921999-12-13 16:37:25 +00006255 else
6256 result = PyInt_FromLong(limit);
6257 }
6258 return result;
6259}
6260#endif
6261
6262#ifdef HAVE_CONFSTR
6263static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006264#ifdef _CS_ARCHITECTURE
6265 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6266#endif
6267#ifdef _CS_HOSTNAME
6268 {"CS_HOSTNAME", _CS_HOSTNAME},
6269#endif
6270#ifdef _CS_HW_PROVIDER
6271 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6272#endif
6273#ifdef _CS_HW_SERIAL
6274 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6275#endif
6276#ifdef _CS_INITTAB_NAME
6277 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6278#endif
Fred Drakec9680921999-12-13 16:37:25 +00006279#ifdef _CS_LFS64_CFLAGS
6280 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6281#endif
6282#ifdef _CS_LFS64_LDFLAGS
6283 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6284#endif
6285#ifdef _CS_LFS64_LIBS
6286 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6287#endif
6288#ifdef _CS_LFS64_LINTFLAGS
6289 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6290#endif
6291#ifdef _CS_LFS_CFLAGS
6292 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6293#endif
6294#ifdef _CS_LFS_LDFLAGS
6295 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6296#endif
6297#ifdef _CS_LFS_LIBS
6298 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6299#endif
6300#ifdef _CS_LFS_LINTFLAGS
6301 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6302#endif
Fred Draked86ed291999-12-15 15:34:33 +00006303#ifdef _CS_MACHINE
6304 {"CS_MACHINE", _CS_MACHINE},
6305#endif
Fred Drakec9680921999-12-13 16:37:25 +00006306#ifdef _CS_PATH
6307 {"CS_PATH", _CS_PATH},
6308#endif
Fred Draked86ed291999-12-15 15:34:33 +00006309#ifdef _CS_RELEASE
6310 {"CS_RELEASE", _CS_RELEASE},
6311#endif
6312#ifdef _CS_SRPC_DOMAIN
6313 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6314#endif
6315#ifdef _CS_SYSNAME
6316 {"CS_SYSNAME", _CS_SYSNAME},
6317#endif
6318#ifdef _CS_VERSION
6319 {"CS_VERSION", _CS_VERSION},
6320#endif
Fred Drakec9680921999-12-13 16:37:25 +00006321#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6322 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6323#endif
6324#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6325 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6326#endif
6327#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6328 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6329#endif
6330#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6331 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6332#endif
6333#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6334 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6335#endif
6336#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6337 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6338#endif
6339#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6340 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6341#endif
6342#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6343 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6344#endif
6345#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6346 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6347#endif
6348#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6349 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6350#endif
6351#ifdef _CS_XBS5_LP64_OFF64_LIBS
6352 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6353#endif
6354#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6355 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6356#endif
6357#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6358 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6359#endif
6360#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6361 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6362#endif
6363#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6364 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6365#endif
6366#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6367 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6368#endif
Fred Draked86ed291999-12-15 15:34:33 +00006369#ifdef _MIPS_CS_AVAIL_PROCESSORS
6370 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6371#endif
6372#ifdef _MIPS_CS_BASE
6373 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6374#endif
6375#ifdef _MIPS_CS_HOSTID
6376 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6377#endif
6378#ifdef _MIPS_CS_HW_NAME
6379 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6380#endif
6381#ifdef _MIPS_CS_NUM_PROCESSORS
6382 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6383#endif
6384#ifdef _MIPS_CS_OSREL_MAJ
6385 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6386#endif
6387#ifdef _MIPS_CS_OSREL_MIN
6388 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6389#endif
6390#ifdef _MIPS_CS_OSREL_PATCH
6391 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6392#endif
6393#ifdef _MIPS_CS_OS_NAME
6394 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6395#endif
6396#ifdef _MIPS_CS_OS_PROVIDER
6397 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6398#endif
6399#ifdef _MIPS_CS_PROCESSORS
6400 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6401#endif
6402#ifdef _MIPS_CS_SERIAL
6403 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6404#endif
6405#ifdef _MIPS_CS_VENDOR
6406 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6407#endif
Fred Drakec9680921999-12-13 16:37:25 +00006408};
6409
6410static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006411conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006412{
6413 return conv_confname(arg, valuep, posix_constants_confstr,
6414 sizeof(posix_constants_confstr)
6415 / sizeof(struct constdef));
6416}
6417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006419"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006420Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006421
6422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006423posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006424{
6425 PyObject *result = NULL;
6426 int name;
6427 char buffer[64];
6428
6429 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6430 int len = confstr(name, buffer, sizeof(buffer));
6431
Fred Drakec9680921999-12-13 16:37:25 +00006432 errno = 0;
6433 if (len == 0) {
6434 if (errno != 0)
6435 posix_error();
6436 else
6437 result = PyString_FromString("");
6438 }
6439 else {
6440 if (len >= sizeof(buffer)) {
6441 result = PyString_FromStringAndSize(NULL, len);
6442 if (result != NULL)
6443 confstr(name, PyString_AS_STRING(result), len+1);
6444 }
6445 else
6446 result = PyString_FromString(buffer);
6447 }
6448 }
6449 return result;
6450}
6451#endif
6452
6453
6454#ifdef HAVE_SYSCONF
6455static struct constdef posix_constants_sysconf[] = {
6456#ifdef _SC_2_CHAR_TERM
6457 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6458#endif
6459#ifdef _SC_2_C_BIND
6460 {"SC_2_C_BIND", _SC_2_C_BIND},
6461#endif
6462#ifdef _SC_2_C_DEV
6463 {"SC_2_C_DEV", _SC_2_C_DEV},
6464#endif
6465#ifdef _SC_2_C_VERSION
6466 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6467#endif
6468#ifdef _SC_2_FORT_DEV
6469 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6470#endif
6471#ifdef _SC_2_FORT_RUN
6472 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6473#endif
6474#ifdef _SC_2_LOCALEDEF
6475 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6476#endif
6477#ifdef _SC_2_SW_DEV
6478 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6479#endif
6480#ifdef _SC_2_UPE
6481 {"SC_2_UPE", _SC_2_UPE},
6482#endif
6483#ifdef _SC_2_VERSION
6484 {"SC_2_VERSION", _SC_2_VERSION},
6485#endif
Fred Draked86ed291999-12-15 15:34:33 +00006486#ifdef _SC_ABI_ASYNCHRONOUS_IO
6487 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6488#endif
6489#ifdef _SC_ACL
6490 {"SC_ACL", _SC_ACL},
6491#endif
Fred Drakec9680921999-12-13 16:37:25 +00006492#ifdef _SC_AIO_LISTIO_MAX
6493 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6494#endif
Fred Drakec9680921999-12-13 16:37:25 +00006495#ifdef _SC_AIO_MAX
6496 {"SC_AIO_MAX", _SC_AIO_MAX},
6497#endif
6498#ifdef _SC_AIO_PRIO_DELTA_MAX
6499 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6500#endif
6501#ifdef _SC_ARG_MAX
6502 {"SC_ARG_MAX", _SC_ARG_MAX},
6503#endif
6504#ifdef _SC_ASYNCHRONOUS_IO
6505 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6506#endif
6507#ifdef _SC_ATEXIT_MAX
6508 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6509#endif
Fred Draked86ed291999-12-15 15:34:33 +00006510#ifdef _SC_AUDIT
6511 {"SC_AUDIT", _SC_AUDIT},
6512#endif
Fred Drakec9680921999-12-13 16:37:25 +00006513#ifdef _SC_AVPHYS_PAGES
6514 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6515#endif
6516#ifdef _SC_BC_BASE_MAX
6517 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6518#endif
6519#ifdef _SC_BC_DIM_MAX
6520 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6521#endif
6522#ifdef _SC_BC_SCALE_MAX
6523 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6524#endif
6525#ifdef _SC_BC_STRING_MAX
6526 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6527#endif
Fred Draked86ed291999-12-15 15:34:33 +00006528#ifdef _SC_CAP
6529 {"SC_CAP", _SC_CAP},
6530#endif
Fred Drakec9680921999-12-13 16:37:25 +00006531#ifdef _SC_CHARCLASS_NAME_MAX
6532 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6533#endif
6534#ifdef _SC_CHAR_BIT
6535 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6536#endif
6537#ifdef _SC_CHAR_MAX
6538 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6539#endif
6540#ifdef _SC_CHAR_MIN
6541 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6542#endif
6543#ifdef _SC_CHILD_MAX
6544 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6545#endif
6546#ifdef _SC_CLK_TCK
6547 {"SC_CLK_TCK", _SC_CLK_TCK},
6548#endif
6549#ifdef _SC_COHER_BLKSZ
6550 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6551#endif
6552#ifdef _SC_COLL_WEIGHTS_MAX
6553 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6554#endif
6555#ifdef _SC_DCACHE_ASSOC
6556 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6557#endif
6558#ifdef _SC_DCACHE_BLKSZ
6559 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6560#endif
6561#ifdef _SC_DCACHE_LINESZ
6562 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6563#endif
6564#ifdef _SC_DCACHE_SZ
6565 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6566#endif
6567#ifdef _SC_DCACHE_TBLKSZ
6568 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6569#endif
6570#ifdef _SC_DELAYTIMER_MAX
6571 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6572#endif
6573#ifdef _SC_EQUIV_CLASS_MAX
6574 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6575#endif
6576#ifdef _SC_EXPR_NEST_MAX
6577 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6578#endif
6579#ifdef _SC_FSYNC
6580 {"SC_FSYNC", _SC_FSYNC},
6581#endif
6582#ifdef _SC_GETGR_R_SIZE_MAX
6583 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6584#endif
6585#ifdef _SC_GETPW_R_SIZE_MAX
6586 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6587#endif
6588#ifdef _SC_ICACHE_ASSOC
6589 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6590#endif
6591#ifdef _SC_ICACHE_BLKSZ
6592 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6593#endif
6594#ifdef _SC_ICACHE_LINESZ
6595 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6596#endif
6597#ifdef _SC_ICACHE_SZ
6598 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6599#endif
Fred Draked86ed291999-12-15 15:34:33 +00006600#ifdef _SC_INF
6601 {"SC_INF", _SC_INF},
6602#endif
Fred Drakec9680921999-12-13 16:37:25 +00006603#ifdef _SC_INT_MAX
6604 {"SC_INT_MAX", _SC_INT_MAX},
6605#endif
6606#ifdef _SC_INT_MIN
6607 {"SC_INT_MIN", _SC_INT_MIN},
6608#endif
6609#ifdef _SC_IOV_MAX
6610 {"SC_IOV_MAX", _SC_IOV_MAX},
6611#endif
Fred Draked86ed291999-12-15 15:34:33 +00006612#ifdef _SC_IP_SECOPTS
6613 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6614#endif
Fred Drakec9680921999-12-13 16:37:25 +00006615#ifdef _SC_JOB_CONTROL
6616 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6617#endif
Fred Draked86ed291999-12-15 15:34:33 +00006618#ifdef _SC_KERN_POINTERS
6619 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6620#endif
6621#ifdef _SC_KERN_SIM
6622 {"SC_KERN_SIM", _SC_KERN_SIM},
6623#endif
Fred Drakec9680921999-12-13 16:37:25 +00006624#ifdef _SC_LINE_MAX
6625 {"SC_LINE_MAX", _SC_LINE_MAX},
6626#endif
6627#ifdef _SC_LOGIN_NAME_MAX
6628 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6629#endif
6630#ifdef _SC_LOGNAME_MAX
6631 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6632#endif
6633#ifdef _SC_LONG_BIT
6634 {"SC_LONG_BIT", _SC_LONG_BIT},
6635#endif
Fred Draked86ed291999-12-15 15:34:33 +00006636#ifdef _SC_MAC
6637 {"SC_MAC", _SC_MAC},
6638#endif
Fred Drakec9680921999-12-13 16:37:25 +00006639#ifdef _SC_MAPPED_FILES
6640 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6641#endif
6642#ifdef _SC_MAXPID
6643 {"SC_MAXPID", _SC_MAXPID},
6644#endif
6645#ifdef _SC_MB_LEN_MAX
6646 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6647#endif
6648#ifdef _SC_MEMLOCK
6649 {"SC_MEMLOCK", _SC_MEMLOCK},
6650#endif
6651#ifdef _SC_MEMLOCK_RANGE
6652 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6653#endif
6654#ifdef _SC_MEMORY_PROTECTION
6655 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6656#endif
6657#ifdef _SC_MESSAGE_PASSING
6658 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6659#endif
Fred Draked86ed291999-12-15 15:34:33 +00006660#ifdef _SC_MMAP_FIXED_ALIGNMENT
6661 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6662#endif
Fred Drakec9680921999-12-13 16:37:25 +00006663#ifdef _SC_MQ_OPEN_MAX
6664 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6665#endif
6666#ifdef _SC_MQ_PRIO_MAX
6667 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6668#endif
Fred Draked86ed291999-12-15 15:34:33 +00006669#ifdef _SC_NACLS_MAX
6670 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6671#endif
Fred Drakec9680921999-12-13 16:37:25 +00006672#ifdef _SC_NGROUPS_MAX
6673 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6674#endif
6675#ifdef _SC_NL_ARGMAX
6676 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6677#endif
6678#ifdef _SC_NL_LANGMAX
6679 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6680#endif
6681#ifdef _SC_NL_MSGMAX
6682 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6683#endif
6684#ifdef _SC_NL_NMAX
6685 {"SC_NL_NMAX", _SC_NL_NMAX},
6686#endif
6687#ifdef _SC_NL_SETMAX
6688 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6689#endif
6690#ifdef _SC_NL_TEXTMAX
6691 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6692#endif
6693#ifdef _SC_NPROCESSORS_CONF
6694 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6695#endif
6696#ifdef _SC_NPROCESSORS_ONLN
6697 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6698#endif
Fred Draked86ed291999-12-15 15:34:33 +00006699#ifdef _SC_NPROC_CONF
6700 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6701#endif
6702#ifdef _SC_NPROC_ONLN
6703 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6704#endif
Fred Drakec9680921999-12-13 16:37:25 +00006705#ifdef _SC_NZERO
6706 {"SC_NZERO", _SC_NZERO},
6707#endif
6708#ifdef _SC_OPEN_MAX
6709 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6710#endif
6711#ifdef _SC_PAGESIZE
6712 {"SC_PAGESIZE", _SC_PAGESIZE},
6713#endif
6714#ifdef _SC_PAGE_SIZE
6715 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6716#endif
6717#ifdef _SC_PASS_MAX
6718 {"SC_PASS_MAX", _SC_PASS_MAX},
6719#endif
6720#ifdef _SC_PHYS_PAGES
6721 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6722#endif
6723#ifdef _SC_PII
6724 {"SC_PII", _SC_PII},
6725#endif
6726#ifdef _SC_PII_INTERNET
6727 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6728#endif
6729#ifdef _SC_PII_INTERNET_DGRAM
6730 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6731#endif
6732#ifdef _SC_PII_INTERNET_STREAM
6733 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6734#endif
6735#ifdef _SC_PII_OSI
6736 {"SC_PII_OSI", _SC_PII_OSI},
6737#endif
6738#ifdef _SC_PII_OSI_CLTS
6739 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6740#endif
6741#ifdef _SC_PII_OSI_COTS
6742 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6743#endif
6744#ifdef _SC_PII_OSI_M
6745 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6746#endif
6747#ifdef _SC_PII_SOCKET
6748 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6749#endif
6750#ifdef _SC_PII_XTI
6751 {"SC_PII_XTI", _SC_PII_XTI},
6752#endif
6753#ifdef _SC_POLL
6754 {"SC_POLL", _SC_POLL},
6755#endif
6756#ifdef _SC_PRIORITIZED_IO
6757 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6758#endif
6759#ifdef _SC_PRIORITY_SCHEDULING
6760 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6761#endif
6762#ifdef _SC_REALTIME_SIGNALS
6763 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6764#endif
6765#ifdef _SC_RE_DUP_MAX
6766 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6767#endif
6768#ifdef _SC_RTSIG_MAX
6769 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6770#endif
6771#ifdef _SC_SAVED_IDS
6772 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6773#endif
6774#ifdef _SC_SCHAR_MAX
6775 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6776#endif
6777#ifdef _SC_SCHAR_MIN
6778 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6779#endif
6780#ifdef _SC_SELECT
6781 {"SC_SELECT", _SC_SELECT},
6782#endif
6783#ifdef _SC_SEMAPHORES
6784 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6785#endif
6786#ifdef _SC_SEM_NSEMS_MAX
6787 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6788#endif
6789#ifdef _SC_SEM_VALUE_MAX
6790 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6791#endif
6792#ifdef _SC_SHARED_MEMORY_OBJECTS
6793 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6794#endif
6795#ifdef _SC_SHRT_MAX
6796 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6797#endif
6798#ifdef _SC_SHRT_MIN
6799 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6800#endif
6801#ifdef _SC_SIGQUEUE_MAX
6802 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6803#endif
6804#ifdef _SC_SIGRT_MAX
6805 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6806#endif
6807#ifdef _SC_SIGRT_MIN
6808 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6809#endif
Fred Draked86ed291999-12-15 15:34:33 +00006810#ifdef _SC_SOFTPOWER
6811 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6812#endif
Fred Drakec9680921999-12-13 16:37:25 +00006813#ifdef _SC_SPLIT_CACHE
6814 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6815#endif
6816#ifdef _SC_SSIZE_MAX
6817 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6818#endif
6819#ifdef _SC_STACK_PROT
6820 {"SC_STACK_PROT", _SC_STACK_PROT},
6821#endif
6822#ifdef _SC_STREAM_MAX
6823 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6824#endif
6825#ifdef _SC_SYNCHRONIZED_IO
6826 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6827#endif
6828#ifdef _SC_THREADS
6829 {"SC_THREADS", _SC_THREADS},
6830#endif
6831#ifdef _SC_THREAD_ATTR_STACKADDR
6832 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6833#endif
6834#ifdef _SC_THREAD_ATTR_STACKSIZE
6835 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6836#endif
6837#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6838 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6839#endif
6840#ifdef _SC_THREAD_KEYS_MAX
6841 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6842#endif
6843#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6844 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6845#endif
6846#ifdef _SC_THREAD_PRIO_INHERIT
6847 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6848#endif
6849#ifdef _SC_THREAD_PRIO_PROTECT
6850 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6851#endif
6852#ifdef _SC_THREAD_PROCESS_SHARED
6853 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6854#endif
6855#ifdef _SC_THREAD_SAFE_FUNCTIONS
6856 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6857#endif
6858#ifdef _SC_THREAD_STACK_MIN
6859 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6860#endif
6861#ifdef _SC_THREAD_THREADS_MAX
6862 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6863#endif
6864#ifdef _SC_TIMERS
6865 {"SC_TIMERS", _SC_TIMERS},
6866#endif
6867#ifdef _SC_TIMER_MAX
6868 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6869#endif
6870#ifdef _SC_TTY_NAME_MAX
6871 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6872#endif
6873#ifdef _SC_TZNAME_MAX
6874 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6875#endif
6876#ifdef _SC_T_IOV_MAX
6877 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6878#endif
6879#ifdef _SC_UCHAR_MAX
6880 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6881#endif
6882#ifdef _SC_UINT_MAX
6883 {"SC_UINT_MAX", _SC_UINT_MAX},
6884#endif
6885#ifdef _SC_UIO_MAXIOV
6886 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6887#endif
6888#ifdef _SC_ULONG_MAX
6889 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6890#endif
6891#ifdef _SC_USHRT_MAX
6892 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6893#endif
6894#ifdef _SC_VERSION
6895 {"SC_VERSION", _SC_VERSION},
6896#endif
6897#ifdef _SC_WORD_BIT
6898 {"SC_WORD_BIT", _SC_WORD_BIT},
6899#endif
6900#ifdef _SC_XBS5_ILP32_OFF32
6901 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6902#endif
6903#ifdef _SC_XBS5_ILP32_OFFBIG
6904 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6905#endif
6906#ifdef _SC_XBS5_LP64_OFF64
6907 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6908#endif
6909#ifdef _SC_XBS5_LPBIG_OFFBIG
6910 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6911#endif
6912#ifdef _SC_XOPEN_CRYPT
6913 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6914#endif
6915#ifdef _SC_XOPEN_ENH_I18N
6916 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6917#endif
6918#ifdef _SC_XOPEN_LEGACY
6919 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6920#endif
6921#ifdef _SC_XOPEN_REALTIME
6922 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6923#endif
6924#ifdef _SC_XOPEN_REALTIME_THREADS
6925 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6926#endif
6927#ifdef _SC_XOPEN_SHM
6928 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6929#endif
6930#ifdef _SC_XOPEN_UNIX
6931 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6932#endif
6933#ifdef _SC_XOPEN_VERSION
6934 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6935#endif
6936#ifdef _SC_XOPEN_XCU_VERSION
6937 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6938#endif
6939#ifdef _SC_XOPEN_XPG2
6940 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6941#endif
6942#ifdef _SC_XOPEN_XPG3
6943 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6944#endif
6945#ifdef _SC_XOPEN_XPG4
6946 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6947#endif
6948};
6949
6950static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006951conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006952{
6953 return conv_confname(arg, valuep, posix_constants_sysconf,
6954 sizeof(posix_constants_sysconf)
6955 / sizeof(struct constdef));
6956}
6957
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006959"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006960Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006961
6962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006963posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006964{
6965 PyObject *result = NULL;
6966 int name;
6967
6968 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6969 int value;
6970
6971 errno = 0;
6972 value = sysconf(name);
6973 if (value == -1 && errno != 0)
6974 posix_error();
6975 else
6976 result = PyInt_FromLong(value);
6977 }
6978 return result;
6979}
6980#endif
6981
6982
Fred Drakebec628d1999-12-15 18:31:10 +00006983/* This code is used to ensure that the tables of configuration value names
6984 * are in sorted order as required by conv_confname(), and also to build the
6985 * the exported dictionaries that are used to publish information about the
6986 * names available on the host platform.
6987 *
6988 * Sorting the table at runtime ensures that the table is properly ordered
6989 * when used, even for platforms we're not able to test on. It also makes
6990 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006991 */
Fred Drakebec628d1999-12-15 18:31:10 +00006992
6993static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006994cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006995{
6996 const struct constdef *c1 =
6997 (const struct constdef *) v1;
6998 const struct constdef *c2 =
6999 (const struct constdef *) v2;
7000
7001 return strcmp(c1->name, c2->name);
7002}
7003
7004static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007005setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007006 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007007{
Fred Drakebec628d1999-12-15 18:31:10 +00007008 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007009 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007010
7011 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7012 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007013 if (d == NULL)
7014 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007015
Barry Warsaw3155db32000-04-13 15:20:40 +00007016 for (i=0; i < tablesize; ++i) {
7017 PyObject *o = PyInt_FromLong(table[i].value);
7018 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7019 Py_XDECREF(o);
7020 Py_DECREF(d);
7021 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007022 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007023 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007024 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007025 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007026}
7027
Fred Drakebec628d1999-12-15 18:31:10 +00007028/* Return -1 on failure, 0 on success. */
7029static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007030setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007031{
7032#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007033 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007034 sizeof(posix_constants_pathconf)
7035 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007036 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007037 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007038#endif
7039#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007040 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007041 sizeof(posix_constants_confstr)
7042 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007043 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007044 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007045#endif
7046#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007047 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007048 sizeof(posix_constants_sysconf)
7049 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007050 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007051 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007052#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007053 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007054}
Fred Draked86ed291999-12-15 15:34:33 +00007055
7056
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007057PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007058"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007059Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007061
7062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007063posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007064{
7065 if (!PyArg_ParseTuple(args, ":abort"))
7066 return NULL;
7067 abort();
7068 /*NOTREACHED*/
7069 Py_FatalError("abort() called from Python code didn't abort!");
7070 return NULL;
7071}
Fred Drakebec628d1999-12-15 18:31:10 +00007072
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007073#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007074PyDoc_STRVAR(win32_startfile__doc__,
7075"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007076\n\
7077This acts like double-clicking the file in Explorer, or giving the file\n\
7078name as an argument to the DOS \"start\" command: the file is opened\n\
7079with whatever application (if any) its extension is associated.\n\
7080\n\
7081startfile returns as soon as the associated application is launched.\n\
7082There is no option to wait for the application to close, and no way\n\
7083to retrieve the application's exit status.\n\
7084\n\
7085The filepath is relative to the current directory. If you want to use\n\
7086an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007087the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007088
7089static PyObject *
7090win32_startfile(PyObject *self, PyObject *args)
7091{
7092 char *filepath;
7093 HINSTANCE rc;
7094 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7095 return NULL;
7096 Py_BEGIN_ALLOW_THREADS
7097 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7098 Py_END_ALLOW_THREADS
7099 if (rc <= (HINSTANCE)32)
7100 return win32_error("startfile", filepath);
7101 Py_INCREF(Py_None);
7102 return Py_None;
7103}
7104#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007105
7106static PyMethodDef posix_methods[] = {
7107 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7108#ifdef HAVE_TTYNAME
7109 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7110#endif
7111 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7112 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007113#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007114 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007115#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007116#ifdef HAVE_LCHOWN
7117 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7118#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007119#ifdef HAVE_CHROOT
7120 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7121#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007122#ifdef HAVE_CTERMID
7123 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
7124#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007125#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007126 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007127#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007128 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007129#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007130#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007131#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007132 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007133#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7135 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7136 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007137#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007138 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007139#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007140#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007141 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007142#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007143 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7144 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7145 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007146 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007147#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007148 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007149#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007150#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007151 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007152#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007153 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007154#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007156#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7158 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7159 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007160#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007161 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007162#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007163 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007164#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007165 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7166 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007167#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007168#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7170 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007171#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007172#ifdef HAVE_FORK1
7173 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
7174#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007175#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007177#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007178#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007179 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00007180#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007181#ifdef HAVE_FORKPTY
7182 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
7183#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007184#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007185 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007186#endif /* HAVE_GETEGID */
7187#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007188 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007189#endif /* HAVE_GETEUID */
7190#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007191 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007192#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007193#ifdef HAVE_GETGROUPS
7194 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
7195#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007197#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007199#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007200#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007201 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007202#endif /* HAVE_GETPPID */
7203#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007204 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007205#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007206#ifdef HAVE_GETLOGIN
7207 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
7208#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007209#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007210 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007211#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007212#ifdef HAVE_KILLPG
7213 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7214#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007215#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007216 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007217#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007218#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007219 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007220#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007221 {"popen2", win32_popen2, METH_VARARGS},
7222 {"popen3", win32_popen3, METH_VARARGS},
7223 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007224 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007225#else
7226#if defined(PYOS_OS2) && defined(PYCC_GCC)
7227 {"popen2", os2emx_popen2, METH_VARARGS},
7228 {"popen3", os2emx_popen3, METH_VARARGS},
7229 {"popen4", os2emx_popen4, METH_VARARGS},
7230#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007231#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007232#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007233#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007234 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007235#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007236#ifdef HAVE_SETEUID
7237 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7238#endif /* HAVE_SETEUID */
7239#ifdef HAVE_SETEGID
7240 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7241#endif /* HAVE_SETEGID */
7242#ifdef HAVE_SETREUID
7243 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7244#endif /* HAVE_SETREUID */
7245#ifdef HAVE_SETREGID
7246 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7247#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007248#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007250#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007251#ifdef HAVE_SETGROUPS
7252 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7253#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007254#ifdef HAVE_GETPGID
7255 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7256#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007257#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007258 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007259#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007260#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007261 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007262#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007263#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007264 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007265#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007266#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007267 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007268#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007269#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007270 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007271#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007272#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007273 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007274#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007275#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007276 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007277#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007278 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7279 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7280 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7281 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7282 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7283 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7284 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7285 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7286 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007287 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007288#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007289 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007290#endif
7291#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007292 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007293#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007294#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007295 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7296#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007297#ifdef HAVE_DEVICE_MACROS
7298 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7299 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7300 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7301#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007302#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007303 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007304#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007305#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007306 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007307#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007308#ifdef HAVE_UNSETENV
7309 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7310#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007311#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007312 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007313#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007314#ifdef HAVE_FCHDIR
7315 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7316#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007317#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007318 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007319#endif
7320#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007321 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007322#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007323#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007324#ifdef WCOREDUMP
7325 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7326#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007327#ifdef WIFCONTINUED
7328 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7329#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007330#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007332#endif /* WIFSTOPPED */
7333#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007334 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007335#endif /* WIFSIGNALED */
7336#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007337 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007338#endif /* WIFEXITED */
7339#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007340 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007341#endif /* WEXITSTATUS */
7342#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007343 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007344#endif /* WTERMSIG */
7345#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007346 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007347#endif /* WSTOPSIG */
7348#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007349#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007350 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007351#endif
7352#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007353 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007354#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007355#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007356 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7357#endif
7358#ifdef HAVE_TEMPNAM
7359 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7360#endif
7361#ifdef HAVE_TMPNAM
7362 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7363#endif
Fred Drakec9680921999-12-13 16:37:25 +00007364#ifdef HAVE_CONFSTR
7365 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7366#endif
7367#ifdef HAVE_SYSCONF
7368 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7369#endif
7370#ifdef HAVE_FPATHCONF
7371 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7372#endif
7373#ifdef HAVE_PATHCONF
7374 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7375#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007376 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007377#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007378 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007380 {NULL, NULL} /* Sentinel */
7381};
7382
7383
Barry Warsaw4a342091996-12-19 23:50:02 +00007384static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007385ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007386{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007387 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007388}
7389
Guido van Rossumd48f2521997-12-05 22:19:34 +00007390#if defined(PYOS_OS2)
7391/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007392static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007393{
7394 APIRET rc;
7395 ULONG values[QSV_MAX+1];
7396 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007397 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007398
7399 Py_BEGIN_ALLOW_THREADS
7400 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7401 Py_END_ALLOW_THREADS
7402
7403 if (rc != NO_ERROR) {
7404 os2_error(rc);
7405 return -1;
7406 }
7407
Fred Drake4d1e64b2002-04-15 19:40:07 +00007408 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7409 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7410 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7411 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7412 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7413 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7414 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007415
7416 switch (values[QSV_VERSION_MINOR]) {
7417 case 0: ver = "2.00"; break;
7418 case 10: ver = "2.10"; break;
7419 case 11: ver = "2.11"; break;
7420 case 30: ver = "3.00"; break;
7421 case 40: ver = "4.00"; break;
7422 case 50: ver = "5.00"; break;
7423 default:
Tim Peters885d4572001-11-28 20:27:42 +00007424 PyOS_snprintf(tmp, sizeof(tmp),
7425 "%d-%d", values[QSV_VERSION_MAJOR],
7426 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007427 ver = &tmp[0];
7428 }
7429
7430 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007431 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007432 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007433
7434 /* Add Indicator of Which Drive was Used to Boot the System */
7435 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7436 tmp[1] = ':';
7437 tmp[2] = '\0';
7438
Fred Drake4d1e64b2002-04-15 19:40:07 +00007439 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007440}
7441#endif
7442
Barry Warsaw4a342091996-12-19 23:50:02 +00007443static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007444all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007445{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007446#ifdef F_OK
7447 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007448#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007449#ifdef R_OK
7450 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007451#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007452#ifdef W_OK
7453 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007454#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007455#ifdef X_OK
7456 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007457#endif
Fred Drakec9680921999-12-13 16:37:25 +00007458#ifdef NGROUPS_MAX
7459 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7460#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007461#ifdef TMP_MAX
7462 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7463#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007464#ifdef WCONTINUED
7465 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7466#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007467#ifdef WNOHANG
7468 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007469#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007470#ifdef WUNTRACED
7471 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7472#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007473#ifdef O_RDONLY
7474 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7475#endif
7476#ifdef O_WRONLY
7477 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7478#endif
7479#ifdef O_RDWR
7480 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7481#endif
7482#ifdef O_NDELAY
7483 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7484#endif
7485#ifdef O_NONBLOCK
7486 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7487#endif
7488#ifdef O_APPEND
7489 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7490#endif
7491#ifdef O_DSYNC
7492 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7493#endif
7494#ifdef O_RSYNC
7495 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7496#endif
7497#ifdef O_SYNC
7498 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7499#endif
7500#ifdef O_NOCTTY
7501 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7502#endif
7503#ifdef O_CREAT
7504 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7505#endif
7506#ifdef O_EXCL
7507 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7508#endif
7509#ifdef O_TRUNC
7510 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7511#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007512#ifdef O_BINARY
7513 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7514#endif
7515#ifdef O_TEXT
7516 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7517#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007518#ifdef O_LARGEFILE
7519 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7520#endif
7521
Tim Peters5aa91602002-01-30 05:46:57 +00007522/* MS Windows */
7523#ifdef O_NOINHERIT
7524 /* Don't inherit in child processes. */
7525 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7526#endif
7527#ifdef _O_SHORT_LIVED
7528 /* Optimize for short life (keep in memory). */
7529 /* MS forgot to define this one with a non-underscore form too. */
7530 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7531#endif
7532#ifdef O_TEMPORARY
7533 /* Automatically delete when last handle is closed. */
7534 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7535#endif
7536#ifdef O_RANDOM
7537 /* Optimize for random access. */
7538 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7539#endif
7540#ifdef O_SEQUENTIAL
7541 /* Optimize for sequential access. */
7542 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7543#endif
7544
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007545/* GNU extensions. */
7546#ifdef O_DIRECT
7547 /* Direct disk access. */
7548 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7549#endif
7550#ifdef O_DIRECTORY
7551 /* Must be a directory. */
7552 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7553#endif
7554#ifdef O_NOFOLLOW
7555 /* Do not follow links. */
7556 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7557#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007558
Guido van Rossum246bc171999-02-01 23:54:31 +00007559#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007560#if defined(PYOS_OS2) && defined(PYCC_GCC)
7561 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7562 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7563 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7564 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7565 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7566 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7567 if (ins(d, "P_PM", (long)P_PM)) return -1;
7568 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7569 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7570 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7571 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7572 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7573 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7574 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7575 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7576 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7577 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7578 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7579 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7580 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7581#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007582 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7583 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7584 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7585 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7586 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007587#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007588#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007589
Guido van Rossumd48f2521997-12-05 22:19:34 +00007590#if defined(PYOS_OS2)
7591 if (insertvalues(d)) return -1;
7592#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007593 return 0;
7594}
7595
7596
Tim Peters5aa91602002-01-30 05:46:57 +00007597#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007598#define INITFUNC initnt
7599#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007600
7601#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007602#define INITFUNC initos2
7603#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007604
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007605#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007606#define INITFUNC initposix
7607#define MODNAME "posix"
7608#endif
7609
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007610PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007611INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007612{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007613 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007614
Fred Drake4d1e64b2002-04-15 19:40:07 +00007615 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007616 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007617 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007618
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007619 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007621 Py_XINCREF(v);
7622 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007623 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007624 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007625
Fred Drake4d1e64b2002-04-15 19:40:07 +00007626 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007627 return;
7628
Fred Drake4d1e64b2002-04-15 19:40:07 +00007629 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007630 return;
7631
Fred Drake4d1e64b2002-04-15 19:40:07 +00007632 Py_INCREF(PyExc_OSError);
7633 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007634
Guido van Rossumb3d39562000-01-31 18:41:26 +00007635#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007636 if (posix_putenv_garbage == NULL)
7637 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007638#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007639
Guido van Rossum14648392001-12-08 18:02:58 +00007640 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007641 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7642 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7643 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007644 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007645 structseq_new = StatResultType.tp_new;
7646 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007647 Py_INCREF((PyObject*) &StatResultType);
7648 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007649
Guido van Rossum14648392001-12-08 18:02:58 +00007650 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007651 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007652 Py_INCREF((PyObject*) &StatVFSResultType);
7653 PyModule_AddObject(m, "statvfs_result",
7654 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655}