blob: ce0bc5b25548fef1740e4e8a88547ecba74e9a1c [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 {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002317 PyErr_SetString(PyExc_TypeError,
2318 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002320 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002321 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002322 PyErr_SetString(PyExc_TypeError,
2323 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002324 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002325 }
2326
Guido van Rossum50422b42000-04-26 20:34:28 +00002327 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002328 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002329 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002330 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002331 }
2332
Barry Warsaw53699e91996-12-10 23:23:01 +00002333 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002336 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002337 }
2338 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002340 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002341 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002342 &argvlist[i]))
2343 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002345 goto fail_1;
2346 }
2347 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002348 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002349 argvlist[argc] = NULL;
2350
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002351 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002352 if (i < 0)
2353 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002354 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002355 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002357 goto fail_1;
2358 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002359 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002360 keys = PyMapping_Keys(env);
2361 vals = PyMapping_Values(env);
2362 if (!keys || !vals)
2363 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002364 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2365 PyErr_SetString(PyExc_TypeError,
2366 "execve(): env.keys() or env.values() is not a list");
2367 goto fail_2;
2368 }
Tim Peters5aa91602002-01-30 05:46:57 +00002369
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002370 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002371 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002372 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002373
2374 key = PyList_GetItem(keys, pos);
2375 val = PyList_GetItem(vals, pos);
2376 if (!key || !val)
2377 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002378
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002379 if (!PyArg_Parse(
2380 key,
2381 "s;execve() arg 3 contains a non-string key",
2382 &k) ||
2383 !PyArg_Parse(
2384 val,
2385 "s;execve() arg 3 contains a non-string value",
2386 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002387 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002388 goto fail_2;
2389 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002390
2391#if defined(PYOS_OS2)
2392 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2393 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2394#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002395 len = PyString_Size(key) + PyString_Size(val) + 2;
2396 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002397 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002398 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002399 goto fail_2;
2400 }
Tim Petersc8996f52001-12-03 20:41:00 +00002401 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002402 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002403#if defined(PYOS_OS2)
2404 }
2405#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002406 }
2407 envlist[envc] = 0;
2408
Guido van Rossumb6775db1994-08-01 11:34:53 +00002409
2410#ifdef BAD_EXEC_PROTOTYPES
2411 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002412#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002413 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002414#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002415
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002416 /* If we get here it's definitely an error */
2417
2418 (void) posix_error();
2419
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002420 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002421 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002422 PyMem_DEL(envlist[envc]);
2423 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002424 fail_1:
2425 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002426 Py_XDECREF(vals);
2427 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002428 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002429 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002430 return NULL;
2431}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002432#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002433
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002434
Guido van Rossuma1065681999-01-25 23:20:23 +00002435#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002436PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002437"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002438Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002439\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002440 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002441 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002442 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002443
2444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002445posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002446{
2447 char *path;
2448 PyObject *argv;
2449 char **argvlist;
2450 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002451 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002452 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002453
2454 /* spawnv has three arguments: (mode, path, argv), where
2455 argv is a list or tuple of strings. */
2456
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2458 Py_FileSystemDefaultEncoding,
2459 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002460 return NULL;
2461 if (PyList_Check(argv)) {
2462 argc = PyList_Size(argv);
2463 getitem = PyList_GetItem;
2464 }
2465 else if (PyTuple_Check(argv)) {
2466 argc = PyTuple_Size(argv);
2467 getitem = PyTuple_GetItem;
2468 }
2469 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002470 PyErr_SetString(PyExc_TypeError,
2471 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002472 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002473 return NULL;
2474 }
2475
2476 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002477 if (argvlist == NULL) {
2478 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002479 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002480 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002481 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002482 if (!PyArg_Parse((*getitem)(argv, i), "et",
2483 Py_FileSystemDefaultEncoding,
2484 &argvlist[i])) {
2485 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002486 PyErr_SetString(
2487 PyExc_TypeError,
2488 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002489 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002490 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002491 }
2492 }
2493 argvlist[argc] = NULL;
2494
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002495#if defined(PYOS_OS2) && defined(PYCC_GCC)
2496 Py_BEGIN_ALLOW_THREADS
2497 spawnval = spawnv(mode, path, argvlist);
2498 Py_END_ALLOW_THREADS
2499#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002500 if (mode == _OLD_P_OVERLAY)
2501 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002502
Tim Peters25059d32001-12-07 20:35:43 +00002503 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002504 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002505 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002506#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002507
Martin v. Löwis114619e2002-10-07 06:44:21 +00002508 free_string_array(argvlist, argc);
2509 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002510
Fred Drake699f3522000-06-29 21:12:41 +00002511 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002512 return posix_error();
2513 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002514#if SIZEOF_LONG == SIZEOF_VOID_P
2515 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002516#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002517 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002518#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002519}
2520
2521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002522PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002523"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002524Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002525\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002526 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002527 path: path of executable file\n\
2528 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002529 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002530
2531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002532posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002533{
2534 char *path;
2535 PyObject *argv, *env;
2536 char **argvlist;
2537 char **envlist;
2538 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2539 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002540 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002542 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002543
2544 /* spawnve has four arguments: (mode, path, argv, env), where
2545 argv is a list or tuple of strings and env is a dictionary
2546 like posix.environ. */
2547
Martin v. Löwis114619e2002-10-07 06:44:21 +00002548 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2549 Py_FileSystemDefaultEncoding,
2550 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002551 return NULL;
2552 if (PyList_Check(argv)) {
2553 argc = PyList_Size(argv);
2554 getitem = PyList_GetItem;
2555 }
2556 else if (PyTuple_Check(argv)) {
2557 argc = PyTuple_Size(argv);
2558 getitem = PyTuple_GetItem;
2559 }
2560 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002561 PyErr_SetString(PyExc_TypeError,
2562 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002563 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002564 }
2565 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002566 PyErr_SetString(PyExc_TypeError,
2567 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002568 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002569 }
2570
2571 argvlist = PyMem_NEW(char *, argc+1);
2572 if (argvlist == NULL) {
2573 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002574 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002575 }
2576 for (i = 0; i < argc; i++) {
2577 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002578 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002579 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002580 &argvlist[i]))
2581 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002582 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002583 goto fail_1;
2584 }
2585 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002587 argvlist[argc] = NULL;
2588
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002589 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002590 if (i < 0)
2591 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002592 envlist = PyMem_NEW(char *, i + 1);
2593 if (envlist == NULL) {
2594 PyErr_NoMemory();
2595 goto fail_1;
2596 }
2597 envc = 0;
2598 keys = PyMapping_Keys(env);
2599 vals = PyMapping_Values(env);
2600 if (!keys || !vals)
2601 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002602 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2603 PyErr_SetString(PyExc_TypeError,
2604 "spawnve(): env.keys() or env.values() is not a list");
2605 goto fail_2;
2606 }
Tim Peters5aa91602002-01-30 05:46:57 +00002607
Guido van Rossuma1065681999-01-25 23:20:23 +00002608 for (pos = 0; pos < i; pos++) {
2609 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002610 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002611
2612 key = PyList_GetItem(keys, pos);
2613 val = PyList_GetItem(vals, pos);
2614 if (!key || !val)
2615 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002616
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002617 if (!PyArg_Parse(
2618 key,
2619 "s;spawnve() arg 3 contains a non-string key",
2620 &k) ||
2621 !PyArg_Parse(
2622 val,
2623 "s;spawnve() arg 3 contains a non-string value",
2624 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002625 {
2626 goto fail_2;
2627 }
Tim Petersc8996f52001-12-03 20:41:00 +00002628 len = PyString_Size(key) + PyString_Size(val) + 2;
2629 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002630 if (p == NULL) {
2631 PyErr_NoMemory();
2632 goto fail_2;
2633 }
Tim Petersc8996f52001-12-03 20:41:00 +00002634 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002635 envlist[envc++] = p;
2636 }
2637 envlist[envc] = 0;
2638
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002639#if defined(PYOS_OS2) && defined(PYCC_GCC)
2640 Py_BEGIN_ALLOW_THREADS
2641 spawnval = spawnve(mode, path, argvlist, envlist);
2642 Py_END_ALLOW_THREADS
2643#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002644 if (mode == _OLD_P_OVERLAY)
2645 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002646
2647 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002648 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002649 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002650#endif
Tim Peters25059d32001-12-07 20:35:43 +00002651
Fred Drake699f3522000-06-29 21:12:41 +00002652 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002653 (void) posix_error();
2654 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002655#if SIZEOF_LONG == SIZEOF_VOID_P
2656 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002657#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002658 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002659#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002660
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002661 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002662 while (--envc >= 0)
2663 PyMem_DEL(envlist[envc]);
2664 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002665 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002666 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002667 Py_XDECREF(vals);
2668 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002669 fail_0:
2670 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002671 return res;
2672}
2673#endif /* HAVE_SPAWNV */
2674
2675
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002676#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002677PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002678"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002679Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2680\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002681Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002682
2683static PyObject *
2684posix_fork1(self, args)
2685 PyObject *self;
2686 PyObject *args;
2687{
2688 int pid;
2689 if (!PyArg_ParseTuple(args, ":fork1"))
2690 return NULL;
2691 pid = fork1();
2692 if (pid == -1)
2693 return posix_error();
2694 PyOS_AfterFork();
2695 return PyInt_FromLong((long)pid);
2696}
2697#endif
2698
2699
Guido van Rossumad0ee831995-03-01 10:34:45 +00002700#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002702"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002703Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002705
Barry Warsaw53699e91996-12-10 23:23:01 +00002706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002707posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002708{
2709 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002710 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002711 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002712 pid = fork();
2713 if (pid == -1)
2714 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002715 if (pid == 0)
2716 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002717 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002718}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002719#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002720
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002721#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002722#ifdef HAVE_PTY_H
2723#include <pty.h>
2724#else
2725#ifdef HAVE_LIBUTIL_H
2726#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002727#endif /* HAVE_LIBUTIL_H */
2728#endif /* HAVE_PTY_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002729#ifdef sun
2730#include <sys/stropts.h>
2731#endif
2732#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002733
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002734#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002735PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002736"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002738
2739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002740posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002741{
2742 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002743#ifndef HAVE_OPENPTY
2744 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002745#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002746#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002747 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002748#ifdef sun
2749 extern char *ptsname();
2750#endif
2751#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002752
Fred Drake8cef4cf2000-06-28 16:40:38 +00002753 if (!PyArg_ParseTuple(args, ":openpty"))
2754 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002755
2756#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002757 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2758 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002759#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002760 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2761 if (slave_name == NULL)
2762 return posix_error();
2763
2764 slave_fd = open(slave_name, O_RDWR);
2765 if (slave_fd < 0)
2766 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002767#else
2768 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2769 if (master_fd < 0)
2770 return posix_error();
2771 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002772 /* change permission of slave */
2773 if (grantpt(master_fd) < 0) {
2774 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002775 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002776 }
2777 /* unlock slave */
2778 if (unlockpt(master_fd) < 0) {
2779 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002780 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002781 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002782 signal(SIGCHLD, sig_saved);
2783 slave_name = ptsname(master_fd); /* get name of slave */
2784 if (slave_name == NULL)
2785 return posix_error();
2786 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2787 if (slave_fd < 0)
2788 return posix_error();
2789#ifndef __CYGWIN__
2790 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2791 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2792#ifndef _hpux
2793 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2794#endif /* _hpux */
2795#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002796#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002797
Fred Drake8cef4cf2000-06-28 16:40:38 +00002798 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002799
Fred Drake8cef4cf2000-06-28 16:40:38 +00002800}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002801#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002802
2803#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002805"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002806Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2807Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002808To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002809
2810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002811posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002812{
2813 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002814
Fred Drake8cef4cf2000-06-28 16:40:38 +00002815 if (!PyArg_ParseTuple(args, ":forkpty"))
2816 return NULL;
2817 pid = forkpty(&master_fd, NULL, NULL, NULL);
2818 if (pid == -1)
2819 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002820 if (pid == 0)
2821 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002822 return Py_BuildValue("(ii)", pid, master_fd);
2823}
2824#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Guido van Rossumad0ee831995-03-01 10:34:45 +00002826#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002827PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002828"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002829Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002830
Barry Warsaw53699e91996-12-10 23:23:01 +00002831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002832posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002833{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002834 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002835 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002836 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002837}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002838#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002840
Guido van Rossumad0ee831995-03-01 10:34:45 +00002841#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002842PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002843"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002844Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002845
Barry Warsaw53699e91996-12-10 23:23:01 +00002846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002847posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002848{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002849 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002850 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002851 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002852}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002853#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Guido van Rossumad0ee831995-03-01 10:34:45 +00002856#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002857PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002858"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002859Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002860
Barry Warsaw53699e91996-12-10 23:23:01 +00002861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002862posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002863{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002864 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002866 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002867}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002868#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002872"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002874
Barry Warsaw53699e91996-12-10 23:23:01 +00002875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002876posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002877{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002878 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002879 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002880 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002881}
2882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002883
Fred Drakec9680921999-12-13 16:37:25 +00002884#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002885PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002886"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002887Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002888
2889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002890posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002891{
2892 PyObject *result = NULL;
2893
2894 if (PyArg_ParseTuple(args, ":getgroups")) {
2895#ifdef NGROUPS_MAX
2896#define MAX_GROUPS NGROUPS_MAX
2897#else
2898 /* defined to be 16 on Solaris7, so this should be a small number */
2899#define MAX_GROUPS 64
2900#endif
2901 gid_t grouplist[MAX_GROUPS];
2902 int n;
2903
2904 n = getgroups(MAX_GROUPS, grouplist);
2905 if (n < 0)
2906 posix_error();
2907 else {
2908 result = PyList_New(n);
2909 if (result != NULL) {
2910 PyObject *o;
2911 int i;
2912 for (i = 0; i < n; ++i) {
2913 o = PyInt_FromLong((long)grouplist[i]);
2914 if (o == NULL) {
2915 Py_DECREF(result);
2916 result = NULL;
2917 break;
2918 }
2919 PyList_SET_ITEM(result, i, o);
2920 }
2921 }
2922 }
2923 }
2924 return result;
2925}
2926#endif
2927
Martin v. Löwis606edc12002-06-13 21:09:11 +00002928#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002929PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002930"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002931Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002932
2933static PyObject *
2934posix_getpgid(PyObject *self, PyObject *args)
2935{
2936 int pid, pgid;
2937 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2938 return NULL;
2939 pgid = getpgid(pid);
2940 if (pgid < 0)
2941 return posix_error();
2942 return PyInt_FromLong((long)pgid);
2943}
2944#endif /* HAVE_GETPGID */
2945
2946
Guido van Rossumb6775db1994-08-01 11:34:53 +00002947#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002948PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002949"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002950Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002951
Barry Warsaw53699e91996-12-10 23:23:01 +00002952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002953posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002954{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002955 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002956 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002957#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002958 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002959#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002960 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002961#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002962}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002963#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002965
Guido van Rossumb6775db1994-08-01 11:34:53 +00002966#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002967PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002968"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002969Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002970
Barry Warsaw53699e91996-12-10 23:23:01 +00002971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002972posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002973{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002974 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002975 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002976#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002977 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002978#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002979 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002980#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002982 Py_INCREF(Py_None);
2983 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002984}
2985
Guido van Rossumb6775db1994-08-01 11:34:53 +00002986#endif /* HAVE_SETPGRP */
2987
Guido van Rossumad0ee831995-03-01 10:34:45 +00002988#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002989PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002990"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002991Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002992
Barry Warsaw53699e91996-12-10 23:23:01 +00002993static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002994posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002995{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002996 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002997 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002998 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002999}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003000#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003002
Fred Drake12c6e2d1999-12-14 21:25:03 +00003003#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003004PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003005"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003007
3008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003009posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003010{
3011 PyObject *result = NULL;
3012
3013 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00003014 char *name;
3015 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003016
Fred Drakea30680b2000-12-06 21:24:28 +00003017 errno = 0;
3018 name = getlogin();
3019 if (name == NULL) {
3020 if (errno)
3021 posix_error();
3022 else
3023 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003024 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003025 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003026 else
3027 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003028 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003029 }
3030 return result;
3031}
3032#endif
3033
Guido van Rossumad0ee831995-03-01 10:34:45 +00003034#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003035PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003036"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003037Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003038
Barry Warsaw53699e91996-12-10 23:23:01 +00003039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003040posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003041{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003042 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00003043 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003045}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003046#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003048
Guido van Rossumad0ee831995-03-01 10:34:45 +00003049#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003050PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003051"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003052Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053
Barry Warsaw53699e91996-12-10 23:23:01 +00003054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003055posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003056{
3057 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003058 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003059 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003060#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003061 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3062 APIRET rc;
3063 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003064 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003065
3066 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3067 APIRET rc;
3068 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003069 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003070
3071 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003072 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003073#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003074 if (kill(pid, sig) == -1)
3075 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003076#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003077 Py_INCREF(Py_None);
3078 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003079}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003080#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003081
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003082#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003084"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003085Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003086
3087static PyObject *
3088posix_killpg(PyObject *self, PyObject *args)
3089{
3090 int pgid, sig;
3091 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3092 return NULL;
3093 if (killpg(pgid, sig) == -1)
3094 return posix_error();
3095 Py_INCREF(Py_None);
3096 return Py_None;
3097}
3098#endif
3099
Guido van Rossumc0125471996-06-28 18:55:32 +00003100#ifdef HAVE_PLOCK
3101
3102#ifdef HAVE_SYS_LOCK_H
3103#include <sys/lock.h>
3104#endif
3105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003106PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003107"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003108Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003109
Barry Warsaw53699e91996-12-10 23:23:01 +00003110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003111posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003112{
3113 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003114 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003115 return NULL;
3116 if (plock(op) == -1)
3117 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003118 Py_INCREF(Py_None);
3119 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003120}
3121#endif
3122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003123
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003124#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003125PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003126"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003127Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003128
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003129#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003130#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003131static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003132async_system(const char *command)
3133{
3134 char *p, errormsg[256], args[1024];
3135 RESULTCODES rcodes;
3136 APIRET rc;
3137 char *shell = getenv("COMSPEC");
3138 if (!shell)
3139 shell = "cmd";
3140
3141 strcpy(args, shell);
3142 p = &args[ strlen(args)+1 ];
3143 strcpy(p, "/c ");
3144 strcat(p, command);
3145 p += strlen(p) + 1;
3146 *p = '\0';
3147
3148 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003149 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003150 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003151 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003152 &rcodes, shell);
3153 return rc;
3154}
3155
Guido van Rossumd48f2521997-12-05 22:19:34 +00003156static FILE *
3157popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003158{
3159 HFILE rhan, whan;
3160 FILE *retfd = NULL;
3161 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3162
Guido van Rossumd48f2521997-12-05 22:19:34 +00003163 if (rc != NO_ERROR) {
3164 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003165 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003166 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003167
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003168 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3169 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003171 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3172 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003173
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003174 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3175 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003176
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003177 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003178 }
3179
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003180 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3181 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003182
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003183 if (rc == NO_ERROR)
3184 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3185
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003186 close(oldfd); /* And Close Saved STDOUT Handle */
3187 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003188
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003189 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3190 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003191
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003192 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3193 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003194
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003195 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3196 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003197
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003198 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003199 }
3200
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003201 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3202 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003203
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003204 if (rc == NO_ERROR)
3205 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3206
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003207 close(oldfd); /* And Close Saved STDIN Handle */
3208 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003209
Guido van Rossumd48f2521997-12-05 22:19:34 +00003210 } else {
3211 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003212 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003213 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003214}
3215
3216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003217posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003218{
3219 char *name;
3220 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003221 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003222 FILE *fp;
3223 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003224 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003225 return NULL;
3226 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003227 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003228 Py_END_ALLOW_THREADS
3229 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003230 return os2_error(err);
3231
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003232 f = PyFile_FromFile(fp, name, mode, fclose);
3233 if (f != NULL)
3234 PyFile_SetBufSize(f, bufsize);
3235 return f;
3236}
3237
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003238#elif defined(PYCC_GCC)
3239
3240/* standard posix version of popen() support */
3241static PyObject *
3242posix_popen(PyObject *self, PyObject *args)
3243{
3244 char *name;
3245 char *mode = "r";
3246 int bufsize = -1;
3247 FILE *fp;
3248 PyObject *f;
3249 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3250 return NULL;
3251 Py_BEGIN_ALLOW_THREADS
3252 fp = popen(name, mode);
3253 Py_END_ALLOW_THREADS
3254 if (fp == NULL)
3255 return posix_error();
3256 f = PyFile_FromFile(fp, name, mode, pclose);
3257 if (f != NULL)
3258 PyFile_SetBufSize(f, bufsize);
3259 return f;
3260}
3261
3262/* fork() under OS/2 has lots'o'warts
3263 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3264 * most of this code is a ripoff of the win32 code, but using the
3265 * capabilities of EMX's C library routines
3266 */
3267
3268/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3269#define POPEN_1 1
3270#define POPEN_2 2
3271#define POPEN_3 3
3272#define POPEN_4 4
3273
3274static PyObject *_PyPopen(char *, int, int, int);
3275static int _PyPclose(FILE *file);
3276
3277/*
3278 * Internal dictionary mapping popen* file pointers to process handles,
3279 * for use when retrieving the process exit code. See _PyPclose() below
3280 * for more information on this dictionary's use.
3281 */
3282static PyObject *_PyPopenProcs = NULL;
3283
3284/* os2emx version of popen2()
3285 *
3286 * The result of this function is a pipe (file) connected to the
3287 * process's stdin, and a pipe connected to the process's stdout.
3288 */
3289
3290static PyObject *
3291os2emx_popen2(PyObject *self, PyObject *args)
3292{
3293 PyObject *f;
3294 int tm=0;
3295
3296 char *cmdstring;
3297 char *mode = "t";
3298 int bufsize = -1;
3299 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3300 return NULL;
3301
3302 if (*mode == 't')
3303 tm = O_TEXT;
3304 else if (*mode != 'b') {
3305 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3306 return NULL;
3307 } else
3308 tm = O_BINARY;
3309
3310 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3311
3312 return f;
3313}
3314
3315/*
3316 * Variation on os2emx.popen2
3317 *
3318 * The result of this function is 3 pipes - the process's stdin,
3319 * stdout and stderr
3320 */
3321
3322static PyObject *
3323os2emx_popen3(PyObject *self, PyObject *args)
3324{
3325 PyObject *f;
3326 int tm = 0;
3327
3328 char *cmdstring;
3329 char *mode = "t";
3330 int bufsize = -1;
3331 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3332 return NULL;
3333
3334 if (*mode == 't')
3335 tm = O_TEXT;
3336 else if (*mode != 'b') {
3337 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3338 return NULL;
3339 } else
3340 tm = O_BINARY;
3341
3342 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3343
3344 return f;
3345}
3346
3347/*
3348 * Variation on os2emx.popen2
3349 *
3350 * The result of this function is 2 pipes - the processes stdin,
3351 * and stdout+stderr combined as a single pipe.
3352 */
3353
3354static PyObject *
3355os2emx_popen4(PyObject *self, PyObject *args)
3356{
3357 PyObject *f;
3358 int tm = 0;
3359
3360 char *cmdstring;
3361 char *mode = "t";
3362 int bufsize = -1;
3363 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3364 return NULL;
3365
3366 if (*mode == 't')
3367 tm = O_TEXT;
3368 else if (*mode != 'b') {
3369 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3370 return NULL;
3371 } else
3372 tm = O_BINARY;
3373
3374 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3375
3376 return f;
3377}
3378
3379/* a couple of structures for convenient handling of multiple
3380 * file handles and pipes
3381 */
3382struct file_ref
3383{
3384 int handle;
3385 int flags;
3386};
3387
3388struct pipe_ref
3389{
3390 int rd;
3391 int wr;
3392};
3393
3394/* The following code is derived from the win32 code */
3395
3396static PyObject *
3397_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3398{
3399 struct file_ref stdio[3];
3400 struct pipe_ref p_fd[3];
3401 FILE *p_s[3];
3402 int file_count, i, pipe_err, pipe_pid;
3403 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3404 PyObject *f, *p_f[3];
3405
3406 /* file modes for subsequent fdopen's on pipe handles */
3407 if (mode == O_TEXT)
3408 {
3409 rd_mode = "rt";
3410 wr_mode = "wt";
3411 }
3412 else
3413 {
3414 rd_mode = "rb";
3415 wr_mode = "wb";
3416 }
3417
3418 /* prepare shell references */
3419 if ((shell = getenv("EMXSHELL")) == NULL)
3420 if ((shell = getenv("COMSPEC")) == NULL)
3421 {
3422 errno = ENOENT;
3423 return posix_error();
3424 }
3425
3426 sh_name = _getname(shell);
3427 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3428 opt = "/c";
3429 else
3430 opt = "-c";
3431
3432 /* save current stdio fds + their flags, and set not inheritable */
3433 i = pipe_err = 0;
3434 while (pipe_err >= 0 && i < 3)
3435 {
3436 pipe_err = stdio[i].handle = dup(i);
3437 stdio[i].flags = fcntl(i, F_GETFD, 0);
3438 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3439 i++;
3440 }
3441 if (pipe_err < 0)
3442 {
3443 /* didn't get them all saved - clean up and bail out */
3444 int saved_err = errno;
3445 while (i-- > 0)
3446 {
3447 close(stdio[i].handle);
3448 }
3449 errno = saved_err;
3450 return posix_error();
3451 }
3452
3453 /* create pipe ends */
3454 file_count = 2;
3455 if (n == POPEN_3)
3456 file_count = 3;
3457 i = pipe_err = 0;
3458 while ((pipe_err == 0) && (i < file_count))
3459 pipe_err = pipe((int *)&p_fd[i++]);
3460 if (pipe_err < 0)
3461 {
3462 /* didn't get them all made - clean up and bail out */
3463 while (i-- > 0)
3464 {
3465 close(p_fd[i].wr);
3466 close(p_fd[i].rd);
3467 }
3468 errno = EPIPE;
3469 return posix_error();
3470 }
3471
3472 /* change the actual standard IO streams over temporarily,
3473 * making the retained pipe ends non-inheritable
3474 */
3475 pipe_err = 0;
3476
3477 /* - stdin */
3478 if (dup2(p_fd[0].rd, 0) == 0)
3479 {
3480 close(p_fd[0].rd);
3481 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3482 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3483 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3484 {
3485 close(p_fd[0].wr);
3486 pipe_err = -1;
3487 }
3488 }
3489 else
3490 {
3491 pipe_err = -1;
3492 }
3493
3494 /* - stdout */
3495 if (pipe_err == 0)
3496 {
3497 if (dup2(p_fd[1].wr, 1) == 1)
3498 {
3499 close(p_fd[1].wr);
3500 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3501 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3502 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3503 {
3504 close(p_fd[1].rd);
3505 pipe_err = -1;
3506 }
3507 }
3508 else
3509 {
3510 pipe_err = -1;
3511 }
3512 }
3513
3514 /* - stderr, as required */
3515 if (pipe_err == 0)
3516 switch (n)
3517 {
3518 case POPEN_3:
3519 {
3520 if (dup2(p_fd[2].wr, 2) == 2)
3521 {
3522 close(p_fd[2].wr);
3523 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3524 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3525 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3526 {
3527 close(p_fd[2].rd);
3528 pipe_err = -1;
3529 }
3530 }
3531 else
3532 {
3533 pipe_err = -1;
3534 }
3535 break;
3536 }
3537
3538 case POPEN_4:
3539 {
3540 if (dup2(1, 2) != 2)
3541 {
3542 pipe_err = -1;
3543 }
3544 break;
3545 }
3546 }
3547
3548 /* spawn the child process */
3549 if (pipe_err == 0)
3550 {
3551 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3552 if (pipe_pid == -1)
3553 {
3554 pipe_err = -1;
3555 }
3556 else
3557 {
3558 /* save the PID into the FILE structure
3559 * NOTE: this implementation doesn't actually
3560 * take advantage of this, but do it for
3561 * completeness - AIM Apr01
3562 */
3563 for (i = 0; i < file_count; i++)
3564 p_s[i]->_pid = pipe_pid;
3565 }
3566 }
3567
3568 /* reset standard IO to normal */
3569 for (i = 0; i < 3; i++)
3570 {
3571 dup2(stdio[i].handle, i);
3572 fcntl(i, F_SETFD, stdio[i].flags);
3573 close(stdio[i].handle);
3574 }
3575
3576 /* if any remnant problems, clean up and bail out */
3577 if (pipe_err < 0)
3578 {
3579 for (i = 0; i < 3; i++)
3580 {
3581 close(p_fd[i].rd);
3582 close(p_fd[i].wr);
3583 }
3584 errno = EPIPE;
3585 return posix_error_with_filename(cmdstring);
3586 }
3587
3588 /* build tuple of file objects to return */
3589 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3590 PyFile_SetBufSize(p_f[0], bufsize);
3591 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3592 PyFile_SetBufSize(p_f[1], bufsize);
3593 if (n == POPEN_3)
3594 {
3595 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3596 PyFile_SetBufSize(p_f[0], bufsize);
3597 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3598 }
3599 else
3600 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3601
3602 /*
3603 * Insert the files we've created into the process dictionary
3604 * all referencing the list with the process handle and the
3605 * initial number of files (see description below in _PyPclose).
3606 * Since if _PyPclose later tried to wait on a process when all
3607 * handles weren't closed, it could create a deadlock with the
3608 * child, we spend some energy here to try to ensure that we
3609 * either insert all file handles into the dictionary or none
3610 * at all. It's a little clumsy with the various popen modes
3611 * and variable number of files involved.
3612 */
3613 if (!_PyPopenProcs)
3614 {
3615 _PyPopenProcs = PyDict_New();
3616 }
3617
3618 if (_PyPopenProcs)
3619 {
3620 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3621 int ins_rc[3];
3622
3623 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3624 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3625
3626 procObj = PyList_New(2);
3627 pidObj = PyInt_FromLong((long) pipe_pid);
3628 intObj = PyInt_FromLong((long) file_count);
3629
3630 if (procObj && pidObj && intObj)
3631 {
3632 PyList_SetItem(procObj, 0, pidObj);
3633 PyList_SetItem(procObj, 1, intObj);
3634
3635 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3636 if (fileObj[0])
3637 {
3638 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3639 fileObj[0],
3640 procObj);
3641 }
3642 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3643 if (fileObj[1])
3644 {
3645 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3646 fileObj[1],
3647 procObj);
3648 }
3649 if (file_count >= 3)
3650 {
3651 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3652 if (fileObj[2])
3653 {
3654 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3655 fileObj[2],
3656 procObj);
3657 }
3658 }
3659
3660 if (ins_rc[0] < 0 || !fileObj[0] ||
3661 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3662 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3663 {
3664 /* Something failed - remove any dictionary
3665 * entries that did make it.
3666 */
3667 if (!ins_rc[0] && fileObj[0])
3668 {
3669 PyDict_DelItem(_PyPopenProcs,
3670 fileObj[0]);
3671 }
3672 if (!ins_rc[1] && fileObj[1])
3673 {
3674 PyDict_DelItem(_PyPopenProcs,
3675 fileObj[1]);
3676 }
3677 if (!ins_rc[2] && fileObj[2])
3678 {
3679 PyDict_DelItem(_PyPopenProcs,
3680 fileObj[2]);
3681 }
3682 }
3683 }
3684
3685 /*
3686 * Clean up our localized references for the dictionary keys
3687 * and value since PyDict_SetItem will Py_INCREF any copies
3688 * that got placed in the dictionary.
3689 */
3690 Py_XDECREF(procObj);
3691 Py_XDECREF(fileObj[0]);
3692 Py_XDECREF(fileObj[1]);
3693 Py_XDECREF(fileObj[2]);
3694 }
3695
3696 /* Child is launched. */
3697 return f;
3698}
3699
3700/*
3701 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3702 * exit code for the child process and return as a result of the close.
3703 *
3704 * This function uses the _PyPopenProcs dictionary in order to map the
3705 * input file pointer to information about the process that was
3706 * originally created by the popen* call that created the file pointer.
3707 * The dictionary uses the file pointer as a key (with one entry
3708 * inserted for each file returned by the original popen* call) and a
3709 * single list object as the value for all files from a single call.
3710 * The list object contains the Win32 process handle at [0], and a file
3711 * count at [1], which is initialized to the total number of file
3712 * handles using that list.
3713 *
3714 * This function closes whichever handle it is passed, and decrements
3715 * the file count in the dictionary for the process handle pointed to
3716 * by this file. On the last close (when the file count reaches zero),
3717 * this function will wait for the child process and then return its
3718 * exit code as the result of the close() operation. This permits the
3719 * files to be closed in any order - it is always the close() of the
3720 * final handle that will return the exit code.
3721 */
3722
3723 /* RED_FLAG 31-Aug-2000 Tim
3724 * This is always called (today!) between a pair of
3725 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3726 * macros. So the thread running this has no valid thread state, as
3727 * far as Python is concerned. However, this calls some Python API
3728 * functions that cannot be called safely without a valid thread
3729 * state, in particular PyDict_GetItem.
3730 * As a temporary hack (although it may last for years ...), we
3731 * *rely* on not having a valid thread state in this function, in
3732 * order to create our own "from scratch".
3733 * This will deadlock if _PyPclose is ever called by a thread
3734 * holding the global lock.
3735 * (The OS/2 EMX thread support appears to cover the case where the
3736 * lock is already held - AIM Apr01)
3737 */
3738
3739static int _PyPclose(FILE *file)
3740{
3741 int result;
3742 int exit_code;
3743 int pipe_pid;
3744 PyObject *procObj, *pidObj, *intObj, *fileObj;
3745 int file_count;
3746#ifdef WITH_THREAD
3747 PyInterpreterState* pInterpreterState;
3748 PyThreadState* pThreadState;
3749#endif
3750
3751 /* Close the file handle first, to ensure it can't block the
3752 * child from exiting if it's the last handle.
3753 */
3754 result = fclose(file);
3755
3756#ifdef WITH_THREAD
3757 /* Bootstrap a valid thread state into existence. */
3758 pInterpreterState = PyInterpreterState_New();
3759 if (!pInterpreterState) {
3760 /* Well, we're hosed now! We don't have a thread
3761 * state, so can't call a nice error routine, or raise
3762 * an exception. Just die.
3763 */
3764 Py_FatalError("unable to allocate interpreter state "
3765 "when closing popen object.");
3766 return -1; /* unreachable */
3767 }
3768 pThreadState = PyThreadState_New(pInterpreterState);
3769 if (!pThreadState) {
3770 Py_FatalError("unable to allocate thread state "
3771 "when closing popen object.");
3772 return -1; /* unreachable */
3773 }
3774 /* Grab the global lock. Note that this will deadlock if the
3775 * current thread already has the lock! (see RED_FLAG comments
3776 * before this function)
3777 */
3778 PyEval_RestoreThread(pThreadState);
3779#endif
3780
3781 if (_PyPopenProcs)
3782 {
3783 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3784 (procObj = PyDict_GetItem(_PyPopenProcs,
3785 fileObj)) != NULL &&
3786 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3787 (intObj = PyList_GetItem(procObj,1)) != NULL)
3788 {
3789 pipe_pid = (int) PyInt_AsLong(pidObj);
3790 file_count = (int) PyInt_AsLong(intObj);
3791
3792 if (file_count > 1)
3793 {
3794 /* Still other files referencing process */
3795 file_count--;
3796 PyList_SetItem(procObj,1,
3797 PyInt_FromLong((long) file_count));
3798 }
3799 else
3800 {
3801 /* Last file for this process */
3802 if (result != EOF &&
3803 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3804 {
3805 /* extract exit status */
3806 if (WIFEXITED(exit_code))
3807 {
3808 result = WEXITSTATUS(exit_code);
3809 }
3810 else
3811 {
3812 errno = EPIPE;
3813 result = -1;
3814 }
3815 }
3816 else
3817 {
3818 /* Indicate failure - this will cause the file object
3819 * to raise an I/O error and translate the last
3820 * error code from errno. We do have a problem with
3821 * last errors that overlap the normal errno table,
3822 * but that's a consistent problem with the file object.
3823 */
3824 result = -1;
3825 }
3826 }
3827
3828 /* Remove this file pointer from dictionary */
3829 PyDict_DelItem(_PyPopenProcs, fileObj);
3830
3831 if (PyDict_Size(_PyPopenProcs) == 0)
3832 {
3833 Py_DECREF(_PyPopenProcs);
3834 _PyPopenProcs = NULL;
3835 }
3836
3837 } /* if object retrieval ok */
3838
3839 Py_XDECREF(fileObj);
3840 } /* if _PyPopenProcs */
3841
3842#ifdef WITH_THREAD
3843 /* Tear down the thread & interpreter states.
3844 * Note that interpreter state clear & delete functions automatically
3845 * call the thread clear & delete functions, and indeed insist on
3846 * doing that themselves. The lock must be held during the clear, but
3847 * need not be held during the delete.
3848 */
3849 PyInterpreterState_Clear(pInterpreterState);
3850 PyEval_ReleaseThread(pThreadState);
3851 PyInterpreterState_Delete(pInterpreterState);
3852#endif
3853
3854 return result;
3855}
3856
3857#endif /* PYCC_??? */
3858
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003859#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003860
3861/*
3862 * Portable 'popen' replacement for Win32.
3863 *
3864 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3865 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003866 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003867 */
3868
3869#include <malloc.h>
3870#include <io.h>
3871#include <fcntl.h>
3872
3873/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3874#define POPEN_1 1
3875#define POPEN_2 2
3876#define POPEN_3 3
3877#define POPEN_4 4
3878
3879static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003880static int _PyPclose(FILE *file);
3881
3882/*
3883 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003884 * for use when retrieving the process exit code. See _PyPclose() below
3885 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003886 */
3887static PyObject *_PyPopenProcs = NULL;
3888
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003889
3890/* popen that works from a GUI.
3891 *
3892 * The result of this function is a pipe (file) connected to the
3893 * processes stdin or stdout, depending on the requested mode.
3894 */
3895
3896static PyObject *
3897posix_popen(PyObject *self, PyObject *args)
3898{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003899 PyObject *f, *s;
3900 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003901
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 char *cmdstring;
3903 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003904 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003905 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003906 return NULL;
3907
3908 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003909
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003910 if (*mode == 'r')
3911 tm = _O_RDONLY;
3912 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003913 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003914 return NULL;
3915 } else
3916 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003917
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003918 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003919 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003920 return NULL;
3921 }
3922
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003923 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003924 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003925 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003926 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003927 else
3928 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3929
3930 return f;
3931}
3932
3933/* Variation on win32pipe.popen
3934 *
3935 * The result of this function is a pipe (file) connected to the
3936 * process's stdin, and a pipe connected to the process's stdout.
3937 */
3938
3939static PyObject *
3940win32_popen2(PyObject *self, PyObject *args)
3941{
3942 PyObject *f;
3943 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003944
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945 char *cmdstring;
3946 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003947 int bufsize = -1;
3948 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003949 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003950
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003951 if (*mode == 't')
3952 tm = _O_TEXT;
3953 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003954 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003955 return NULL;
3956 } else
3957 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003958
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003959 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003960 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003961 return NULL;
3962 }
3963
3964 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003965
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003966 return f;
3967}
3968
3969/*
3970 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003971 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003972 * The result of this function is 3 pipes - the process's stdin,
3973 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 */
3975
3976static PyObject *
3977win32_popen3(PyObject *self, PyObject *args)
3978{
3979 PyObject *f;
3980 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003981
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003982 char *cmdstring;
3983 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003984 int bufsize = -1;
3985 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003987
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003988 if (*mode == 't')
3989 tm = _O_TEXT;
3990 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003991 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003992 return NULL;
3993 } else
3994 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003995
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003996 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003997 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003998 return NULL;
3999 }
4000
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004001 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004002
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004003 return f;
4004}
4005
4006/*
4007 * Variation on win32pipe.popen
4008 *
Tim Peters5aa91602002-01-30 05:46:57 +00004009 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004010 * and stdout+stderr combined as a single pipe.
4011 */
4012
4013static PyObject *
4014win32_popen4(PyObject *self, PyObject *args)
4015{
4016 PyObject *f;
4017 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004018
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 char *cmdstring;
4020 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004021 int bufsize = -1;
4022 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004023 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004024
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004025 if (*mode == 't')
4026 tm = _O_TEXT;
4027 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004028 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004029 return NULL;
4030 } else
4031 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004032
4033 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004034 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004035 return NULL;
4036 }
4037
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004038 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004039
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004040 return f;
4041}
4042
Mark Hammond08501372001-01-31 07:30:29 +00004043static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004044_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004045 HANDLE hStdin,
4046 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004047 HANDLE hStderr,
4048 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004049{
4050 PROCESS_INFORMATION piProcInfo;
4051 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004052 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004053 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004054 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004055 int i;
4056 int x;
4057
4058 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004059 char *comshell;
4060
Tim Peters92e4dd82002-10-05 01:47:34 +00004061 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004062 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4063 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004064
4065 /* Explicitly check if we are using COMMAND.COM. If we are
4066 * then use the w9xpopen hack.
4067 */
4068 comshell = s1 + x;
4069 while (comshell >= s1 && *comshell != '\\')
4070 --comshell;
4071 ++comshell;
4072
4073 if (GetVersion() < 0x80000000 &&
4074 _stricmp(comshell, "command.com") != 0) {
4075 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004076 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004077 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004078 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004079 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004080 }
4081 else {
4082 /*
Tim Peters402d5982001-08-27 06:37:48 +00004083 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4084 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004085 */
Mark Hammond08501372001-01-31 07:30:29 +00004086 char modulepath[_MAX_PATH];
4087 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004088 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4089 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004090 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004091 x = i+1;
4092 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004093 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004094 strncat(modulepath,
4095 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004096 (sizeof(modulepath)/sizeof(modulepath[0]))
4097 -strlen(modulepath));
4098 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004099 /* Eeek - file-not-found - possibly an embedding
4100 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004101 */
Tim Peters5aa91602002-01-30 05:46:57 +00004102 strncpy(modulepath,
4103 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004104 sizeof(modulepath)/sizeof(modulepath[0]));
4105 if (modulepath[strlen(modulepath)-1] != '\\')
4106 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004107 strncat(modulepath,
4108 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004109 (sizeof(modulepath)/sizeof(modulepath[0]))
4110 -strlen(modulepath));
4111 /* No where else to look - raise an easily identifiable
4112 error, rather than leaving Windows to report
4113 "file not found" - as the user is probably blissfully
4114 unaware this shim EXE is used, and it will confuse them.
4115 (well, it confused me for a while ;-)
4116 */
4117 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004118 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004119 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004120 "for popen to work with your shell "
4121 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004122 szConsoleSpawn);
4123 return FALSE;
4124 }
4125 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004126 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004127 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004128 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004129
Tim Peters92e4dd82002-10-05 01:47:34 +00004130 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004132 /* To maintain correct argument passing semantics,
4133 we pass the command-line as it stands, and allow
4134 quoting to be applied. w9xpopen.exe will then
4135 use its argv vector, and re-quote the necessary
4136 args for the ultimate child process.
4137 */
Tim Peters75cdad52001-11-28 22:07:30 +00004138 PyOS_snprintf(
4139 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004140 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004141 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004142 s1,
4143 s3,
4144 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004145 /* Not passing CREATE_NEW_CONSOLE has been known to
4146 cause random failures on win9x. Specifically a
4147 dialog:
4148 "Your program accessed mem currently in use at xxx"
4149 and a hopeful warning about the stability of your
4150 system.
4151 Cost is Ctrl+C wont kill children, but anyone
4152 who cares can have a go!
4153 */
4154 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004155 }
4156 }
4157
4158 /* Could be an else here to try cmd.exe / command.com in the path
4159 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004160 else {
Tim Peters402d5982001-08-27 06:37:48 +00004161 PyErr_SetString(PyExc_RuntimeError,
4162 "Cannot locate a COMSPEC environment variable to "
4163 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004164 return FALSE;
4165 }
Tim Peters5aa91602002-01-30 05:46:57 +00004166
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4168 siStartInfo.cb = sizeof(STARTUPINFO);
4169 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4170 siStartInfo.hStdInput = hStdin;
4171 siStartInfo.hStdOutput = hStdout;
4172 siStartInfo.hStdError = hStderr;
4173 siStartInfo.wShowWindow = SW_HIDE;
4174
4175 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004176 s2,
4177 NULL,
4178 NULL,
4179 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004180 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004181 NULL,
4182 NULL,
4183 &siStartInfo,
4184 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004185 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004186 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004187
Mark Hammondb37a3732000-08-14 04:47:33 +00004188 /* Return process handle */
4189 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004190 return TRUE;
4191 }
Tim Peters402d5982001-08-27 06:37:48 +00004192 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004193 return FALSE;
4194}
4195
4196/* The following code is based off of KB: Q190351 */
4197
4198static PyObject *
4199_PyPopen(char *cmdstring, int mode, int n)
4200{
4201 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4202 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004203 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004204
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004205 SECURITY_ATTRIBUTES saAttr;
4206 BOOL fSuccess;
4207 int fd1, fd2, fd3;
4208 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004209 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004210 PyObject *f;
4211
4212 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4213 saAttr.bInheritHandle = TRUE;
4214 saAttr.lpSecurityDescriptor = NULL;
4215
4216 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4217 return win32_error("CreatePipe", NULL);
4218
4219 /* Create new output read handle and the input write handle. Set
4220 * the inheritance properties to FALSE. Otherwise, the child inherits
4221 * the these handles; resulting in non-closeable handles to the pipes
4222 * being created. */
4223 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004224 GetCurrentProcess(), &hChildStdinWrDup, 0,
4225 FALSE,
4226 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004227 if (!fSuccess)
4228 return win32_error("DuplicateHandle", NULL);
4229
4230 /* Close the inheritable version of ChildStdin
4231 that we're using. */
4232 CloseHandle(hChildStdinWr);
4233
4234 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4235 return win32_error("CreatePipe", NULL);
4236
4237 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004238 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4239 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004240 if (!fSuccess)
4241 return win32_error("DuplicateHandle", NULL);
4242
4243 /* Close the inheritable version of ChildStdout
4244 that we're using. */
4245 CloseHandle(hChildStdoutRd);
4246
4247 if (n != POPEN_4) {
4248 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4249 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004250 fSuccess = DuplicateHandle(GetCurrentProcess(),
4251 hChildStderrRd,
4252 GetCurrentProcess(),
4253 &hChildStderrRdDup, 0,
4254 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004255 if (!fSuccess)
4256 return win32_error("DuplicateHandle", NULL);
4257 /* Close the inheritable version of ChildStdErr that we're using. */
4258 CloseHandle(hChildStderrRd);
4259 }
Tim Peters5aa91602002-01-30 05:46:57 +00004260
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 switch (n) {
4262 case POPEN_1:
4263 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4264 case _O_WRONLY | _O_TEXT:
4265 /* Case for writing to child Stdin in text mode. */
4266 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4267 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004268 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004269 PyFile_SetBufSize(f, 0);
4270 /* We don't care about these pipes anymore, so close them. */
4271 CloseHandle(hChildStdoutRdDup);
4272 CloseHandle(hChildStderrRdDup);
4273 break;
4274
4275 case _O_RDONLY | _O_TEXT:
4276 /* Case for reading from child Stdout in text mode. */
4277 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4278 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004279 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004280 PyFile_SetBufSize(f, 0);
4281 /* We don't care about these pipes anymore, so close them. */
4282 CloseHandle(hChildStdinWrDup);
4283 CloseHandle(hChildStderrRdDup);
4284 break;
4285
4286 case _O_RDONLY | _O_BINARY:
4287 /* Case for readinig from child Stdout in binary mode. */
4288 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4289 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004290 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004291 PyFile_SetBufSize(f, 0);
4292 /* We don't care about these pipes anymore, so close them. */
4293 CloseHandle(hChildStdinWrDup);
4294 CloseHandle(hChildStderrRdDup);
4295 break;
4296
4297 case _O_WRONLY | _O_BINARY:
4298 /* Case for writing to child Stdin in binary mode. */
4299 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4300 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004301 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004302 PyFile_SetBufSize(f, 0);
4303 /* We don't care about these pipes anymore, so close them. */
4304 CloseHandle(hChildStdoutRdDup);
4305 CloseHandle(hChildStderrRdDup);
4306 break;
4307 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004308 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004309 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004310
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004311 case POPEN_2:
4312 case POPEN_4:
4313 {
4314 char *m1, *m2;
4315 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004316
Tim Peters7dca21e2002-08-19 00:42:29 +00004317 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318 m1 = "r";
4319 m2 = "w";
4320 } else {
4321 m1 = "rb";
4322 m2 = "wb";
4323 }
4324
4325 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4326 f1 = _fdopen(fd1, m2);
4327 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4328 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004329 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004330 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004331 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004332 PyFile_SetBufSize(p2, 0);
4333
4334 if (n != 4)
4335 CloseHandle(hChildStderrRdDup);
4336
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004337 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004338 Py_XDECREF(p1);
4339 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004340 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004341 break;
4342 }
Tim Peters5aa91602002-01-30 05:46:57 +00004343
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004344 case POPEN_3:
4345 {
4346 char *m1, *m2;
4347 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004348
Tim Peters7dca21e2002-08-19 00:42:29 +00004349 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004350 m1 = "r";
4351 m2 = "w";
4352 } else {
4353 m1 = "rb";
4354 m2 = "wb";
4355 }
4356
4357 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4358 f1 = _fdopen(fd1, m2);
4359 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4360 f2 = _fdopen(fd2, m1);
4361 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4362 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004363 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004364 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4365 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004366 PyFile_SetBufSize(p1, 0);
4367 PyFile_SetBufSize(p2, 0);
4368 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004369 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004370 Py_XDECREF(p1);
4371 Py_XDECREF(p2);
4372 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004373 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004374 break;
4375 }
4376 }
4377
4378 if (n == POPEN_4) {
4379 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004380 hChildStdinRd,
4381 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004382 hChildStdoutWr,
4383 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004384 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004385 }
4386 else {
4387 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004388 hChildStdinRd,
4389 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004390 hChildStderrWr,
4391 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004392 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004393 }
4394
Mark Hammondb37a3732000-08-14 04:47:33 +00004395 /*
4396 * Insert the files we've created into the process dictionary
4397 * all referencing the list with the process handle and the
4398 * initial number of files (see description below in _PyPclose).
4399 * Since if _PyPclose later tried to wait on a process when all
4400 * handles weren't closed, it could create a deadlock with the
4401 * child, we spend some energy here to try to ensure that we
4402 * either insert all file handles into the dictionary or none
4403 * at all. It's a little clumsy with the various popen modes
4404 * and variable number of files involved.
4405 */
4406 if (!_PyPopenProcs) {
4407 _PyPopenProcs = PyDict_New();
4408 }
4409
4410 if (_PyPopenProcs) {
4411 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4412 int ins_rc[3];
4413
4414 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4415 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4416
4417 procObj = PyList_New(2);
4418 hProcessObj = PyLong_FromVoidPtr(hProcess);
4419 intObj = PyInt_FromLong(file_count);
4420
4421 if (procObj && hProcessObj && intObj) {
4422 PyList_SetItem(procObj,0,hProcessObj);
4423 PyList_SetItem(procObj,1,intObj);
4424
4425 fileObj[0] = PyLong_FromVoidPtr(f1);
4426 if (fileObj[0]) {
4427 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4428 fileObj[0],
4429 procObj);
4430 }
4431 if (file_count >= 2) {
4432 fileObj[1] = PyLong_FromVoidPtr(f2);
4433 if (fileObj[1]) {
4434 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4435 fileObj[1],
4436 procObj);
4437 }
4438 }
4439 if (file_count >= 3) {
4440 fileObj[2] = PyLong_FromVoidPtr(f3);
4441 if (fileObj[2]) {
4442 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4443 fileObj[2],
4444 procObj);
4445 }
4446 }
4447
4448 if (ins_rc[0] < 0 || !fileObj[0] ||
4449 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4450 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4451 /* Something failed - remove any dictionary
4452 * entries that did make it.
4453 */
4454 if (!ins_rc[0] && fileObj[0]) {
4455 PyDict_DelItem(_PyPopenProcs,
4456 fileObj[0]);
4457 }
4458 if (!ins_rc[1] && fileObj[1]) {
4459 PyDict_DelItem(_PyPopenProcs,
4460 fileObj[1]);
4461 }
4462 if (!ins_rc[2] && fileObj[2]) {
4463 PyDict_DelItem(_PyPopenProcs,
4464 fileObj[2]);
4465 }
4466 }
4467 }
Tim Peters5aa91602002-01-30 05:46:57 +00004468
Mark Hammondb37a3732000-08-14 04:47:33 +00004469 /*
4470 * Clean up our localized references for the dictionary keys
4471 * and value since PyDict_SetItem will Py_INCREF any copies
4472 * that got placed in the dictionary.
4473 */
4474 Py_XDECREF(procObj);
4475 Py_XDECREF(fileObj[0]);
4476 Py_XDECREF(fileObj[1]);
4477 Py_XDECREF(fileObj[2]);
4478 }
4479
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004480 /* Child is launched. Close the parents copy of those pipe
4481 * handles that only the child should have open. You need to
4482 * make sure that no handles to the write end of the output pipe
4483 * are maintained in this process or else the pipe will not close
4484 * when the child process exits and the ReadFile will hang. */
4485
4486 if (!CloseHandle(hChildStdinRd))
4487 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004488
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004489 if (!CloseHandle(hChildStdoutWr))
4490 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004491
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004492 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4493 return win32_error("CloseHandle", NULL);
4494
4495 return f;
4496}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004497
4498/*
4499 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4500 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004501 *
4502 * This function uses the _PyPopenProcs dictionary in order to map the
4503 * input file pointer to information about the process that was
4504 * originally created by the popen* call that created the file pointer.
4505 * The dictionary uses the file pointer as a key (with one entry
4506 * inserted for each file returned by the original popen* call) and a
4507 * single list object as the value for all files from a single call.
4508 * The list object contains the Win32 process handle at [0], and a file
4509 * count at [1], which is initialized to the total number of file
4510 * handles using that list.
4511 *
4512 * This function closes whichever handle it is passed, and decrements
4513 * the file count in the dictionary for the process handle pointed to
4514 * by this file. On the last close (when the file count reaches zero),
4515 * this function will wait for the child process and then return its
4516 * exit code as the result of the close() operation. This permits the
4517 * files to be closed in any order - it is always the close() of the
4518 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004519 */
Tim Peters736aa322000-09-01 06:51:24 +00004520
4521 /* RED_FLAG 31-Aug-2000 Tim
4522 * This is always called (today!) between a pair of
4523 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4524 * macros. So the thread running this has no valid thread state, as
4525 * far as Python is concerned. However, this calls some Python API
4526 * functions that cannot be called safely without a valid thread
4527 * state, in particular PyDict_GetItem.
4528 * As a temporary hack (although it may last for years ...), we
4529 * *rely* on not having a valid thread state in this function, in
4530 * order to create our own "from scratch".
4531 * This will deadlock if _PyPclose is ever called by a thread
4532 * holding the global lock.
4533 */
4534
Fredrik Lundh56055a42000-07-23 19:47:12 +00004535static int _PyPclose(FILE *file)
4536{
Fredrik Lundh20318932000-07-26 17:29:12 +00004537 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004538 DWORD exit_code;
4539 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004540 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4541 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004542#ifdef WITH_THREAD
4543 PyInterpreterState* pInterpreterState;
4544 PyThreadState* pThreadState;
4545#endif
4546
Fredrik Lundh20318932000-07-26 17:29:12 +00004547 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004548 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004549 */
4550 result = fclose(file);
4551
Tim Peters736aa322000-09-01 06:51:24 +00004552#ifdef WITH_THREAD
4553 /* Bootstrap a valid thread state into existence. */
4554 pInterpreterState = PyInterpreterState_New();
4555 if (!pInterpreterState) {
4556 /* Well, we're hosed now! We don't have a thread
4557 * state, so can't call a nice error routine, or raise
4558 * an exception. Just die.
4559 */
4560 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004561 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004562 return -1; /* unreachable */
4563 }
4564 pThreadState = PyThreadState_New(pInterpreterState);
4565 if (!pThreadState) {
4566 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004567 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004568 return -1; /* unreachable */
4569 }
4570 /* Grab the global lock. Note that this will deadlock if the
4571 * current thread already has the lock! (see RED_FLAG comments
4572 * before this function)
4573 */
4574 PyEval_RestoreThread(pThreadState);
4575#endif
4576
Fredrik Lundh56055a42000-07-23 19:47:12 +00004577 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004578 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4579 (procObj = PyDict_GetItem(_PyPopenProcs,
4580 fileObj)) != NULL &&
4581 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4582 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4583
4584 hProcess = PyLong_AsVoidPtr(hProcessObj);
4585 file_count = PyInt_AsLong(intObj);
4586
4587 if (file_count > 1) {
4588 /* Still other files referencing process */
4589 file_count--;
4590 PyList_SetItem(procObj,1,
4591 PyInt_FromLong(file_count));
4592 } else {
4593 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004594 if (result != EOF &&
4595 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4596 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004597 /* Possible truncation here in 16-bit environments, but
4598 * real exit codes are just the lower byte in any event.
4599 */
4600 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004601 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004602 /* Indicate failure - this will cause the file object
4603 * to raise an I/O error and translate the last Win32
4604 * error code from errno. We do have a problem with
4605 * last errors that overlap the normal errno table,
4606 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004607 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004608 if (result != EOF) {
4609 /* If the error wasn't from the fclose(), then
4610 * set errno for the file object error handling.
4611 */
4612 errno = GetLastError();
4613 }
4614 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004615 }
4616
4617 /* Free up the native handle at this point */
4618 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004619 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004620
Mark Hammondb37a3732000-08-14 04:47:33 +00004621 /* Remove this file pointer from dictionary */
4622 PyDict_DelItem(_PyPopenProcs, fileObj);
4623
4624 if (PyDict_Size(_PyPopenProcs) == 0) {
4625 Py_DECREF(_PyPopenProcs);
4626 _PyPopenProcs = NULL;
4627 }
4628
4629 } /* if object retrieval ok */
4630
4631 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004632 } /* if _PyPopenProcs */
4633
Tim Peters736aa322000-09-01 06:51:24 +00004634#ifdef WITH_THREAD
4635 /* Tear down the thread & interpreter states.
4636 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004637 * call the thread clear & delete functions, and indeed insist on
4638 * doing that themselves. The lock must be held during the clear, but
4639 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004640 */
4641 PyInterpreterState_Clear(pInterpreterState);
4642 PyEval_ReleaseThread(pThreadState);
4643 PyInterpreterState_Delete(pInterpreterState);
4644#endif
4645
Fredrik Lundh56055a42000-07-23 19:47:12 +00004646 return result;
4647}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004648
4649#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004651posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004652{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004653 char *name;
4654 char *mode = "r";
4655 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004656 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004657 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004658 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004659 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004660 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004661 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004662 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004663 if (fp == NULL)
4664 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004665 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004666 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004667 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004668 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004669}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004670
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004671#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004672#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004674
Guido van Rossumb6775db1994-08-01 11:34:53 +00004675#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004676PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004677"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004678Set the current process's user id.");
4679
Barry Warsaw53699e91996-12-10 23:23:01 +00004680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004681posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004682{
4683 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004684 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004685 return NULL;
4686 if (setuid(uid) < 0)
4687 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004688 Py_INCREF(Py_None);
4689 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004690}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004691#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004693
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004694#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004695PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004696"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004697Set the current process's effective user id.");
4698
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004699static PyObject *
4700posix_seteuid (PyObject *self, PyObject *args)
4701{
4702 int euid;
4703 if (!PyArg_ParseTuple(args, "i", &euid)) {
4704 return NULL;
4705 } else if (seteuid(euid) < 0) {
4706 return posix_error();
4707 } else {
4708 Py_INCREF(Py_None);
4709 return Py_None;
4710 }
4711}
4712#endif /* HAVE_SETEUID */
4713
4714#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004715PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004716"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004717Set the current process's effective group id.");
4718
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004719static PyObject *
4720posix_setegid (PyObject *self, PyObject *args)
4721{
4722 int egid;
4723 if (!PyArg_ParseTuple(args, "i", &egid)) {
4724 return NULL;
4725 } else if (setegid(egid) < 0) {
4726 return posix_error();
4727 } else {
4728 Py_INCREF(Py_None);
4729 return Py_None;
4730 }
4731}
4732#endif /* HAVE_SETEGID */
4733
4734#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004735PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004736"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004737Set the current process's real and effective user ids.");
4738
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004739static PyObject *
4740posix_setreuid (PyObject *self, PyObject *args)
4741{
4742 int ruid, euid;
4743 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4744 return NULL;
4745 } else if (setreuid(ruid, euid) < 0) {
4746 return posix_error();
4747 } else {
4748 Py_INCREF(Py_None);
4749 return Py_None;
4750 }
4751}
4752#endif /* HAVE_SETREUID */
4753
4754#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004756"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757Set the current process's real and effective group ids.");
4758
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004759static PyObject *
4760posix_setregid (PyObject *self, PyObject *args)
4761{
4762 int rgid, egid;
4763 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4764 return NULL;
4765 } else if (setregid(rgid, egid) < 0) {
4766 return posix_error();
4767 } else {
4768 Py_INCREF(Py_None);
4769 return Py_None;
4770 }
4771}
4772#endif /* HAVE_SETREGID */
4773
Guido van Rossumb6775db1994-08-01 11:34:53 +00004774#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004778
Barry Warsaw53699e91996-12-10 23:23:01 +00004779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004780posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004781{
4782 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004783 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004784 return NULL;
4785 if (setgid(gid) < 0)
4786 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004787 Py_INCREF(Py_None);
4788 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004789}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004790#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004791
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004792#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004794"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004795Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004796
4797static PyObject *
4798posix_setgroups(PyObject *self, PyObject *args)
4799{
4800 PyObject *groups;
4801 int i, len;
4802 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004803
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004804 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4805 return NULL;
4806 if (!PySequence_Check(groups)) {
4807 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4808 return NULL;
4809 }
4810 len = PySequence_Size(groups);
4811 if (len > MAX_GROUPS) {
4812 PyErr_SetString(PyExc_ValueError, "too many groups");
4813 return NULL;
4814 }
4815 for(i = 0; i < len; i++) {
4816 PyObject *elem;
4817 elem = PySequence_GetItem(groups, i);
4818 if (!elem)
4819 return NULL;
4820 if (!PyInt_Check(elem)) {
4821 PyErr_SetString(PyExc_TypeError,
4822 "groups must be integers");
4823 Py_DECREF(elem);
4824 return NULL;
4825 }
4826 /* XXX: check that value fits into gid_t. */
4827 grouplist[i] = PyInt_AsLong(elem);
4828 Py_DECREF(elem);
4829 }
4830
4831 if (setgroups(len, grouplist) < 0)
4832 return posix_error();
4833 Py_INCREF(Py_None);
4834 return Py_None;
4835}
4836#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004837
Guido van Rossumb6775db1994-08-01 11:34:53 +00004838#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004840"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004842
Barry Warsaw53699e91996-12-10 23:23:01 +00004843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004844posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004845{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004846 int pid, options;
4847#ifdef UNION_WAIT
4848 union wait status;
4849#define status_i (status.w_status)
4850#else
4851 int status;
4852#define status_i status
4853#endif
4854 status_i = 0;
4855
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004856 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004857 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004858 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004859 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004860 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004861 if (pid == -1)
4862 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004863 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004864 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004865}
4866
Tim Petersab034fa2002-02-01 11:27:43 +00004867#elif defined(HAVE_CWAIT)
4868
4869/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004870PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004871"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004872"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004873
4874static PyObject *
4875posix_waitpid(PyObject *self, PyObject *args)
4876{
4877 int pid, options;
4878 int status;
4879
4880 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4881 return NULL;
4882 Py_BEGIN_ALLOW_THREADS
4883 pid = _cwait(&status, pid, options);
4884 Py_END_ALLOW_THREADS
4885 if (pid == -1)
4886 return posix_error();
4887 else
4888 /* shift the status left a byte so this is more like the
4889 POSIX waitpid */
4890 return Py_BuildValue("ii", pid, status << 8);
4891}
4892#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004893
Guido van Rossumad0ee831995-03-01 10:34:45 +00004894#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004896"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004898
Barry Warsaw53699e91996-12-10 23:23:01 +00004899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004901{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004902 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004903#ifdef UNION_WAIT
4904 union wait status;
4905#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004906#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004907 int status;
4908#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004909#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910 if (!PyArg_ParseTuple(args, ":wait"))
4911 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004912 status_i = 0;
4913 Py_BEGIN_ALLOW_THREADS
4914 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004915 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004916 if (pid == -1)
4917 return posix_error();
4918 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004919 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004920#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004921}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004922#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004925PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004926"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004927Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Barry Warsaw53699e91996-12-10 23:23:01 +00004929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004930posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004931{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004932#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004933 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004934#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004935#ifdef MS_WINDOWS
4936 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4937#else
4938 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4939#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004940#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004941}
4942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004943
Guido van Rossumb6775db1994-08-01 11:34:53 +00004944#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004945PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004946"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004947Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004948
Barry Warsaw53699e91996-12-10 23:23:01 +00004949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004950posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004951{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004952 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004953 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004954 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004955 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004956 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004957 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004958 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004959 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004960 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004961 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004963}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004964#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004966
Guido van Rossumb6775db1994-08-01 11:34:53 +00004967#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004969"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004971
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004973posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004974{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004975 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004976}
4977#endif /* HAVE_SYMLINK */
4978
4979
4980#ifdef HAVE_TIMES
4981#ifndef HZ
4982#define HZ 60 /* Universal constant :-) */
4983#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004984
Guido van Rossumd48f2521997-12-05 22:19:34 +00004985#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4986static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004987system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004988{
4989 ULONG value = 0;
4990
4991 Py_BEGIN_ALLOW_THREADS
4992 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4993 Py_END_ALLOW_THREADS
4994
4995 return value;
4996}
4997
4998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004999posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005000{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005001 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00005002 return NULL;
5003
5004 /* Currently Only Uptime is Provided -- Others Later */
5005 return Py_BuildValue("ddddd",
5006 (double)0 /* t.tms_utime / HZ */,
5007 (double)0 /* t.tms_stime / HZ */,
5008 (double)0 /* t.tms_cutime / HZ */,
5009 (double)0 /* t.tms_cstime / HZ */,
5010 (double)system_uptime() / 1000);
5011}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005012#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005014posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005015{
5016 struct tms t;
5017 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005018 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00005019 return NULL;
5020 errno = 0;
5021 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005022 if (c == (clock_t) -1)
5023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005025 (double)t.tms_utime / HZ,
5026 (double)t.tms_stime / HZ,
5027 (double)t.tms_cutime / HZ,
5028 (double)t.tms_cstime / HZ,
5029 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005030}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005031#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005032#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005033
5034
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005035#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005036#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005038posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005039{
5040 FILETIME create, exit, kernel, user;
5041 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005043 return NULL;
5044 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005045 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5046 /* The fields of a FILETIME structure are the hi and lo part
5047 of a 64-bit value expressed in 100 nanosecond units.
5048 1e7 is one second in such units; 1e-7 the inverse.
5049 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5050 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005051 return Py_BuildValue(
5052 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005053 (double)(kernel.dwHighDateTime*429.4967296 +
5054 kernel.dwLowDateTime*1e-7),
5055 (double)(user.dwHighDateTime*429.4967296 +
5056 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005057 (double)0,
5058 (double)0,
5059 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005060}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005061#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005062
5063#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005064PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005065"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005066Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005067#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Guido van Rossumb6775db1994-08-01 11:34:53 +00005070#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005071PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005072"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005073Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005074
Barry Warsaw53699e91996-12-10 23:23:01 +00005075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005076posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005077{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005078 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005079 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005080 if (setsid() < 0)
5081 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005082 Py_INCREF(Py_None);
5083 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005084}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005085#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005086
Guido van Rossumb6775db1994-08-01 11:34:53 +00005087#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005089"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005091
Barry Warsaw53699e91996-12-10 23:23:01 +00005092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005093posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005094{
5095 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005097 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005098 if (setpgid(pid, pgrp) < 0)
5099 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005100 Py_INCREF(Py_None);
5101 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005102}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005103#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005105
Guido van Rossumb6775db1994-08-01 11:34:53 +00005106#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005107PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005108"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005109Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005110
Barry Warsaw53699e91996-12-10 23:23:01 +00005111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005112posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005113{
5114 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005115 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005116 return NULL;
5117 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005118 if (pgid < 0)
5119 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005120 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005121}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005122#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005124
Guido van Rossumb6775db1994-08-01 11:34:53 +00005125#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005126PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005127"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Barry Warsaw53699e91996-12-10 23:23:01 +00005130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005131posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005132{
5133 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005134 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005135 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005136 if (tcsetpgrp(fd, pgid) < 0)
5137 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005138 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005139 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005140}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005141#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005142
Guido van Rossum687dd131993-05-17 08:34:16 +00005143/* Functions acting on file descriptors */
5144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005145PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005146"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005148
Barry Warsaw53699e91996-12-10 23:23:01 +00005149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005151{
Mark Hammondef8b6542001-05-13 08:04:26 +00005152 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005153 int flag;
5154 int mode = 0777;
5155 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005156
5157#ifdef MS_WINDOWS
5158 if (unicode_file_names()) {
5159 PyUnicodeObject *po;
5160 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5161 Py_BEGIN_ALLOW_THREADS
5162 /* PyUnicode_AS_UNICODE OK without thread
5163 lock as it is a simple dereference. */
5164 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5165 Py_END_ALLOW_THREADS
5166 if (fd < 0)
5167 return posix_error();
5168 return PyInt_FromLong((long)fd);
5169 }
5170 /* Drop the argument parsing error as narrow strings
5171 are also valid. */
5172 PyErr_Clear();
5173 }
5174#endif
5175
Tim Peters5aa91602002-01-30 05:46:57 +00005176 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005177 Py_FileSystemDefaultEncoding, &file,
5178 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005179 return NULL;
5180
Barry Warsaw53699e91996-12-10 23:23:01 +00005181 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005182 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005184 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005185 return posix_error_with_allocated_filename(file);
5186 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005188}
5189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005193Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005194
Barry Warsaw53699e91996-12-10 23:23:01 +00005195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005196posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005197{
5198 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005200 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005201 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005202 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005203 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005204 if (res < 0)
5205 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005206 Py_INCREF(Py_None);
5207 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005208}
5209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005211PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005212"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005213Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005214
Barry Warsaw53699e91996-12-10 23:23:01 +00005215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005216posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005217{
5218 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005219 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005220 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005221 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005222 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005223 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005224 if (fd < 0)
5225 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005226 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005227}
5228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005231"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005233
Barry Warsaw53699e91996-12-10 23:23:01 +00005234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005235posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005236{
5237 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005238 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005239 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005240 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005241 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005242 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005243 if (res < 0)
5244 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005245 Py_INCREF(Py_None);
5246 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005247}
5248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005250PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005251"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005252Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005253
Barry Warsaw53699e91996-12-10 23:23:01 +00005254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005255posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005256{
5257 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005258#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005259 LONG_LONG pos, res;
5260#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005261 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005262#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005263 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005264 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005265 return NULL;
5266#ifdef SEEK_SET
5267 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5268 switch (how) {
5269 case 0: how = SEEK_SET; break;
5270 case 1: how = SEEK_CUR; break;
5271 case 2: how = SEEK_END; break;
5272 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005273#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005274
5275#if !defined(HAVE_LARGEFILE_SUPPORT)
5276 pos = PyInt_AsLong(posobj);
5277#else
5278 pos = PyLong_Check(posobj) ?
5279 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5280#endif
5281 if (PyErr_Occurred())
5282 return NULL;
5283
Barry Warsaw53699e91996-12-10 23:23:01 +00005284 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005285#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005286 res = _lseeki64(fd, pos, how);
5287#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005288 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005289#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005290 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005291 if (res < 0)
5292 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005293
5294#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005295 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005296#else
5297 return PyLong_FromLongLong(res);
5298#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005299}
5300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005305
Barry Warsaw53699e91996-12-10 23:23:01 +00005306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005307posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005308{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005309 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005310 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005311 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005312 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005313 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005314 if (buffer == NULL)
5315 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005316 Py_BEGIN_ALLOW_THREADS
5317 n = read(fd, PyString_AsString(buffer), size);
5318 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005319 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005320 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005321 return posix_error();
5322 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005323 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005324 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005325 return buffer;
5326}
5327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005330"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005332
Barry Warsaw53699e91996-12-10 23:23:01 +00005333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005334posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005335{
5336 int fd, size;
5337 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005338 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005339 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005340 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005341 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005342 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005343 if (size < 0)
5344 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005345 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005346}
5347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005350"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005352
Barry Warsaw53699e91996-12-10 23:23:01 +00005353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005354posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005355{
5356 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005357 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005358 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005360 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005361 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005362 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005363 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005364 if (res != 0)
5365 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005366
Fred Drake699f3522000-06-29 21:12:41 +00005367 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005368}
5369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005371PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005372"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005373Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005374
Barry Warsaw53699e91996-12-10 23:23:01 +00005375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005376posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005377{
Guido van Rossum687dd131993-05-17 08:34:16 +00005378 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005379 char *mode = "r";
5380 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005381 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005382 PyObject *f;
5383 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005384 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005385
Thomas Heller1f043e22002-11-07 16:00:59 +00005386 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5387 PyErr_Format(PyExc_ValueError,
5388 "invalid file mode '%s'", mode);
5389 return NULL;
5390 }
5391
Barry Warsaw53699e91996-12-10 23:23:01 +00005392 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005393 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005394 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005395 if (fp == NULL)
5396 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005397 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005398 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005399 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005400 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005401}
5402
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005404"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005405Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005406connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005407
5408static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005409posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005410{
5411 int fd;
5412 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5413 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005414 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005415}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005416
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005417#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005418PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005419"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005420Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005421
Barry Warsaw53699e91996-12-10 23:23:01 +00005422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005423posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005424{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005425#if defined(PYOS_OS2)
5426 HFILE read, write;
5427 APIRET rc;
5428
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005429 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005430 return NULL;
5431
5432 Py_BEGIN_ALLOW_THREADS
5433 rc = DosCreatePipe( &read, &write, 4096);
5434 Py_END_ALLOW_THREADS
5435 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005436 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005437
5438 return Py_BuildValue("(ii)", read, write);
5439#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005440#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005441 int fds[2];
5442 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005443 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005444 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005445 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005446#if defined(__VMS)
5447 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5448#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005449 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005450#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005451 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005452 if (res != 0)
5453 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005454 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005455#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005456 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005457 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005458 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005459 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005460 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005461 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005462 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005463 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005464 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005465 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005466 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5467 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005468 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005469#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005470#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005471}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005472#endif /* HAVE_PIPE */
5473
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005474
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005475#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005476PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005477"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005479
Barry Warsaw53699e91996-12-10 23:23:01 +00005480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005481posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005482{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005483 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005484 int mode = 0666;
5485 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005486 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005488 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005489 res = mkfifo(filename, mode);
5490 Py_END_ALLOW_THREADS
5491 if (res < 0)
5492 return posix_error();
5493 Py_INCREF(Py_None);
5494 return Py_None;
5495}
5496#endif
5497
5498
Neal Norwitz11690112002-07-30 01:08:28 +00005499#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005501"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005502Create a filesystem node (file, device special file or named pipe)\n\
5503named filename. mode specifies both the permissions to use and the\n\
5504type of node to be created, being combined (bitwise OR) with one of\n\
5505S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005506device defines the newly created device special file (probably using\n\
5507os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005508
5509
5510static PyObject *
5511posix_mknod(PyObject *self, PyObject *args)
5512{
5513 char *filename;
5514 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005515 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005516 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005517 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005518 return NULL;
5519 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005520 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005521 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005522 if (res < 0)
5523 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005524 Py_INCREF(Py_None);
5525 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005526}
5527#endif
5528
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005529#ifdef HAVE_DEVICE_MACROS
5530PyDoc_STRVAR(posix_major__doc__,
5531"major(device) -> major number\n\
5532Extracts a device major number from a raw device number.");
5533
5534static PyObject *
5535posix_major(PyObject *self, PyObject *args)
5536{
5537 int device;
5538 if (!PyArg_ParseTuple(args, "i:major", &device))
5539 return NULL;
5540 return PyInt_FromLong((long)major(device));
5541}
5542
5543PyDoc_STRVAR(posix_minor__doc__,
5544"minor(device) -> minor number\n\
5545Extracts a device minor number from a raw device number.");
5546
5547static PyObject *
5548posix_minor(PyObject *self, PyObject *args)
5549{
5550 int device;
5551 if (!PyArg_ParseTuple(args, "i:minor", &device))
5552 return NULL;
5553 return PyInt_FromLong((long)minor(device));
5554}
5555
5556PyDoc_STRVAR(posix_makedev__doc__,
5557"makedev(major, minor) -> device number\n\
5558Composes a raw device number from the major and minor device numbers.");
5559
5560static PyObject *
5561posix_makedev(PyObject *self, PyObject *args)
5562{
5563 int major, minor;
5564 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5565 return NULL;
5566 return PyInt_FromLong((long)makedev(major, minor));
5567}
5568#endif /* device macros */
5569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005571#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005573"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005575
Barry Warsaw53699e91996-12-10 23:23:01 +00005576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005577posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005578{
5579 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005580 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005581 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005582 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005584 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005585 return NULL;
5586
5587#if !defined(HAVE_LARGEFILE_SUPPORT)
5588 length = PyInt_AsLong(lenobj);
5589#else
5590 length = PyLong_Check(lenobj) ?
5591 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5592#endif
5593 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005594 return NULL;
5595
Barry Warsaw53699e91996-12-10 23:23:01 +00005596 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005597 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005599 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005600 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005601 return NULL;
5602 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005603 Py_INCREF(Py_None);
5604 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005605}
5606#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005607
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005608#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005610"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005612
Fred Drake762e2061999-08-26 17:23:54 +00005613/* Save putenv() parameters as values here, so we can collect them when they
5614 * get re-set with another call for the same key. */
5615static PyObject *posix_putenv_garbage;
5616
Tim Peters5aa91602002-01-30 05:46:57 +00005617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005618posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005619{
5620 char *s1, *s2;
5621 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005622 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005623 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005625 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005626 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005627
5628#if defined(PYOS_OS2)
5629 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5630 APIRET rc;
5631
5632 if (strlen(s2) == 0) /* If New Value is an Empty String */
5633 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5634
5635 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5636 if (rc != NO_ERROR)
5637 return os2_error(rc);
5638
5639 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5640 APIRET rc;
5641
5642 if (strlen(s2) == 0) /* If New Value is an Empty String */
5643 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5644
5645 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5646 if (rc != NO_ERROR)
5647 return os2_error(rc);
5648 } else {
5649#endif
5650
Fred Drake762e2061999-08-26 17:23:54 +00005651 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005652 len = strlen(s1) + strlen(s2) + 2;
5653 /* len includes space for a trailing \0; the size arg to
5654 PyString_FromStringAndSize does not count that */
5655 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005656 if (newstr == NULL)
5657 return PyErr_NoMemory();
5658 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005659 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005660 if (putenv(new)) {
5661 posix_error();
5662 return NULL;
5663 }
Fred Drake762e2061999-08-26 17:23:54 +00005664 /* Install the first arg and newstr in posix_putenv_garbage;
5665 * this will cause previous value to be collected. This has to
5666 * happen after the real putenv() call because the old value
5667 * was still accessible until then. */
5668 if (PyDict_SetItem(posix_putenv_garbage,
5669 PyTuple_GET_ITEM(args, 0), newstr)) {
5670 /* really not much we can do; just leak */
5671 PyErr_Clear();
5672 }
5673 else {
5674 Py_DECREF(newstr);
5675 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005676
5677#if defined(PYOS_OS2)
5678 }
5679#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005680 Py_INCREF(Py_None);
5681 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005682}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005683#endif /* putenv */
5684
Guido van Rossumc524d952001-10-19 01:31:59 +00005685#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005686PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005687"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005689
5690static PyObject *
5691posix_unsetenv(PyObject *self, PyObject *args)
5692{
5693 char *s1;
5694
5695 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5696 return NULL;
5697
5698 unsetenv(s1);
5699
5700 /* Remove the key from posix_putenv_garbage;
5701 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005702 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005703 * old value was still accessible until then.
5704 */
5705 if (PyDict_DelItem(posix_putenv_garbage,
5706 PyTuple_GET_ITEM(args, 0))) {
5707 /* really not much we can do; just leak */
5708 PyErr_Clear();
5709 }
5710
5711 Py_INCREF(Py_None);
5712 return Py_None;
5713}
5714#endif /* unsetenv */
5715
Guido van Rossumb6a47161997-09-15 22:54:34 +00005716#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005718"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005720
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005722posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005723{
5724 int code;
5725 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005726 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005727 return NULL;
5728 message = strerror(code);
5729 if (message == NULL) {
5730 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005731 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005732 return NULL;
5733 }
5734 return PyString_FromString(message);
5735}
5736#endif /* strerror */
5737
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005738
Guido van Rossumc9641791998-08-04 15:26:23 +00005739#ifdef HAVE_SYS_WAIT_H
5740
Fred Drake106c1a02002-04-23 15:58:02 +00005741#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005743"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005745
5746static PyObject *
5747posix_WCOREDUMP(PyObject *self, PyObject *args)
5748{
5749#ifdef UNION_WAIT
5750 union wait status;
5751#define status_i (status.w_status)
5752#else
5753 int status;
5754#define status_i status
5755#endif
5756 status_i = 0;
5757
5758 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5759 {
5760 return NULL;
5761 }
5762
5763 return PyBool_FromLong(WCOREDUMP(status));
5764#undef status_i
5765}
5766#endif /* WCOREDUMP */
5767
5768#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005769PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005770"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005771Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005773
5774static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005775posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005776{
5777#ifdef UNION_WAIT
5778 union wait status;
5779#define status_i (status.w_status)
5780#else
5781 int status;
5782#define status_i status
5783#endif
5784 status_i = 0;
5785
5786 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5787 {
5788 return NULL;
5789 }
5790
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005791 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005792#undef status_i
5793}
5794#endif /* WIFCONTINUED */
5795
Guido van Rossumc9641791998-08-04 15:26:23 +00005796#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005797PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005798"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005799Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005800
5801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005802posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005803{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005804#ifdef UNION_WAIT
5805 union wait status;
5806#define status_i (status.w_status)
5807#else
5808 int status;
5809#define status_i status
5810#endif
5811 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005812
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005813 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005814 {
5815 return NULL;
5816 }
Tim Peters5aa91602002-01-30 05:46:57 +00005817
Fred Drake106c1a02002-04-23 15:58:02 +00005818 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005819#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005820}
5821#endif /* WIFSTOPPED */
5822
5823#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005824PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005825"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005826Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005827
5828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005829posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005830{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005831#ifdef UNION_WAIT
5832 union wait status;
5833#define status_i (status.w_status)
5834#else
5835 int status;
5836#define status_i status
5837#endif
5838 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005839
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005840 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005841 {
5842 return NULL;
5843 }
Tim Peters5aa91602002-01-30 05:46:57 +00005844
Fred Drake106c1a02002-04-23 15:58:02 +00005845 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005846#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005847}
5848#endif /* WIFSIGNALED */
5849
5850#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005851PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005852"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005853Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005854system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005855
5856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005857posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005858{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005859#ifdef UNION_WAIT
5860 union wait status;
5861#define status_i (status.w_status)
5862#else
5863 int status;
5864#define status_i status
5865#endif
5866 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005867
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005868 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005869 {
5870 return NULL;
5871 }
Tim Peters5aa91602002-01-30 05:46:57 +00005872
Fred Drake106c1a02002-04-23 15:58:02 +00005873 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005874#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005875}
5876#endif /* WIFEXITED */
5877
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005878#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005880"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005882
5883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005884posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005885{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005886#ifdef UNION_WAIT
5887 union wait status;
5888#define status_i (status.w_status)
5889#else
5890 int status;
5891#define status_i status
5892#endif
5893 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005894
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005895 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005896 {
5897 return NULL;
5898 }
Tim Peters5aa91602002-01-30 05:46:57 +00005899
Guido van Rossumc9641791998-08-04 15:26:23 +00005900 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005901#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005902}
5903#endif /* WEXITSTATUS */
5904
5905#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005908Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005909value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005910
5911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005912posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005913{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005914#ifdef UNION_WAIT
5915 union wait status;
5916#define status_i (status.w_status)
5917#else
5918 int status;
5919#define status_i status
5920#endif
5921 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005923 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005924 {
5925 return NULL;
5926 }
Tim Peters5aa91602002-01-30 05:46:57 +00005927
Guido van Rossumc9641791998-08-04 15:26:23 +00005928 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005929#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005930}
5931#endif /* WTERMSIG */
5932
5933#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005935"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936Return the signal that stopped the process that provided\n\
5937the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005938
5939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005940posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005941{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005942#ifdef UNION_WAIT
5943 union wait status;
5944#define status_i (status.w_status)
5945#else
5946 int status;
5947#define status_i status
5948#endif
5949 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005950
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005951 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005952 {
5953 return NULL;
5954 }
Tim Peters5aa91602002-01-30 05:46:57 +00005955
Guido van Rossumc9641791998-08-04 15:26:23 +00005956 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005957#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005958}
5959#endif /* WSTOPSIG */
5960
5961#endif /* HAVE_SYS_WAIT_H */
5962
5963
Guido van Rossum94f6f721999-01-06 18:42:14 +00005964#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005965#ifdef _SCO_DS
5966/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5967 needed definitions in sys/statvfs.h */
5968#define _SVID3
5969#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005970#include <sys/statvfs.h>
5971
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005972static PyObject*
5973_pystatvfs_fromstructstatvfs(struct statvfs st) {
5974 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5975 if (v == NULL)
5976 return NULL;
5977
5978#if !defined(HAVE_LARGEFILE_SUPPORT)
5979 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5980 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5981 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5982 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5983 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5984 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5985 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5986 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5987 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5988 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5989#else
5990 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5991 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005992 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005993 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005994 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005995 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5996 PyStructSequence_SET_ITEM(v, 4,
5997 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005998 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005999 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006000 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006001 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006002 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006003 PyLong_FromLongLong((LONG_LONG) st.f_favail));
6004 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6005 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6006#endif
6007
6008 return v;
6009}
6010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006014
6015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006017{
6018 int fd, res;
6019 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006020
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006021 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006022 return NULL;
6023 Py_BEGIN_ALLOW_THREADS
6024 res = fstatvfs(fd, &st);
6025 Py_END_ALLOW_THREADS
6026 if (res != 0)
6027 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006028
6029 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006030}
6031#endif /* HAVE_FSTATVFS */
6032
6033
6034#if defined(HAVE_STATVFS)
6035#include <sys/statvfs.h>
6036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006037PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006038"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006040
6041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006042posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006043{
6044 char *path;
6045 int res;
6046 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006047 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006048 return NULL;
6049 Py_BEGIN_ALLOW_THREADS
6050 res = statvfs(path, &st);
6051 Py_END_ALLOW_THREADS
6052 if (res != 0)
6053 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006054
6055 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006056}
6057#endif /* HAVE_STATVFS */
6058
6059
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006060#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006062"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006063Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006064The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006066
6067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006068posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006069{
6070 PyObject *result = NULL;
6071 char *dir = NULL;
6072 char *pfx = NULL;
6073 char *name;
6074
6075 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6076 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006077
6078 if (PyErr_Warn(PyExc_RuntimeWarning,
6079 "tempnam is a potential security risk to your program") < 0)
6080 return NULL;
6081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006082#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006083 name = _tempnam(dir, pfx);
6084#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006085 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006086#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006087 if (name == NULL)
6088 return PyErr_NoMemory();
6089 result = PyString_FromString(name);
6090 free(name);
6091 return result;
6092}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006093#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006094
6095
6096#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006100
6101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006102posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006103{
6104 FILE *fp;
6105
6106 if (!PyArg_ParseTuple(args, ":tmpfile"))
6107 return NULL;
6108 fp = tmpfile();
6109 if (fp == NULL)
6110 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006111 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112}
6113#endif
6114
6115
6116#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006120
6121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006122posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006123{
6124 char buffer[L_tmpnam];
6125 char *name;
6126
6127 if (!PyArg_ParseTuple(args, ":tmpnam"))
6128 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006129
6130 if (PyErr_Warn(PyExc_RuntimeWarning,
6131 "tmpnam is a potential security risk to your program") < 0)
6132 return NULL;
6133
Greg Wardb48bc172000-03-01 21:51:56 +00006134#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006135 name = tmpnam_r(buffer);
6136#else
6137 name = tmpnam(buffer);
6138#endif
6139 if (name == NULL) {
6140 PyErr_SetObject(PyExc_OSError,
6141 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006142#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006143 "unexpected NULL from tmpnam_r"
6144#else
6145 "unexpected NULL from tmpnam"
6146#endif
6147 ));
6148 return NULL;
6149 }
6150 return PyString_FromString(buffer);
6151}
6152#endif
6153
6154
Fred Drakec9680921999-12-13 16:37:25 +00006155/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6156 * It maps strings representing configuration variable names to
6157 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006158 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006159 * rarely-used constants. There are three separate tables that use
6160 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006161 *
6162 * This code is always included, even if none of the interfaces that
6163 * need it are included. The #if hackery needed to avoid it would be
6164 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006165 */
6166struct constdef {
6167 char *name;
6168 long value;
6169};
6170
Fred Drake12c6e2d1999-12-14 21:25:03 +00006171static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006172conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6173 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006174{
6175 if (PyInt_Check(arg)) {
6176 *valuep = PyInt_AS_LONG(arg);
6177 return 1;
6178 }
6179 if (PyString_Check(arg)) {
6180 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006181 size_t lo = 0;
6182 size_t mid;
6183 size_t hi = tablesize;
6184 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006185 char *confname = PyString_AS_STRING(arg);
6186 while (lo < hi) {
6187 mid = (lo + hi) / 2;
6188 cmp = strcmp(confname, table[mid].name);
6189 if (cmp < 0)
6190 hi = mid;
6191 else if (cmp > 0)
6192 lo = mid + 1;
6193 else {
6194 *valuep = table[mid].value;
6195 return 1;
6196 }
6197 }
6198 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6199 }
6200 else
6201 PyErr_SetString(PyExc_TypeError,
6202 "configuration names must be strings or integers");
6203 return 0;
6204}
6205
6206
6207#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6208static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006209#ifdef _PC_ABI_AIO_XFER_MAX
6210 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6211#endif
6212#ifdef _PC_ABI_ASYNC_IO
6213 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6214#endif
Fred Drakec9680921999-12-13 16:37:25 +00006215#ifdef _PC_ASYNC_IO
6216 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6217#endif
6218#ifdef _PC_CHOWN_RESTRICTED
6219 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6220#endif
6221#ifdef _PC_FILESIZEBITS
6222 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6223#endif
6224#ifdef _PC_LAST
6225 {"PC_LAST", _PC_LAST},
6226#endif
6227#ifdef _PC_LINK_MAX
6228 {"PC_LINK_MAX", _PC_LINK_MAX},
6229#endif
6230#ifdef _PC_MAX_CANON
6231 {"PC_MAX_CANON", _PC_MAX_CANON},
6232#endif
6233#ifdef _PC_MAX_INPUT
6234 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6235#endif
6236#ifdef _PC_NAME_MAX
6237 {"PC_NAME_MAX", _PC_NAME_MAX},
6238#endif
6239#ifdef _PC_NO_TRUNC
6240 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6241#endif
6242#ifdef _PC_PATH_MAX
6243 {"PC_PATH_MAX", _PC_PATH_MAX},
6244#endif
6245#ifdef _PC_PIPE_BUF
6246 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6247#endif
6248#ifdef _PC_PRIO_IO
6249 {"PC_PRIO_IO", _PC_PRIO_IO},
6250#endif
6251#ifdef _PC_SOCK_MAXBUF
6252 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6253#endif
6254#ifdef _PC_SYNC_IO
6255 {"PC_SYNC_IO", _PC_SYNC_IO},
6256#endif
6257#ifdef _PC_VDISABLE
6258 {"PC_VDISABLE", _PC_VDISABLE},
6259#endif
6260};
6261
Fred Drakec9680921999-12-13 16:37:25 +00006262static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006263conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006264{
6265 return conv_confname(arg, valuep, posix_constants_pathconf,
6266 sizeof(posix_constants_pathconf)
6267 / sizeof(struct constdef));
6268}
6269#endif
6270
6271#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006273"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006274Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006275If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006276
6277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006278posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006279{
6280 PyObject *result = NULL;
6281 int name, fd;
6282
Fred Drake12c6e2d1999-12-14 21:25:03 +00006283 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6284 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006285 long limit;
6286
6287 errno = 0;
6288 limit = fpathconf(fd, name);
6289 if (limit == -1 && errno != 0)
6290 posix_error();
6291 else
6292 result = PyInt_FromLong(limit);
6293 }
6294 return result;
6295}
6296#endif
6297
6298
6299#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006302Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006304
6305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006306posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006307{
6308 PyObject *result = NULL;
6309 int name;
6310 char *path;
6311
6312 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6313 conv_path_confname, &name)) {
6314 long limit;
6315
6316 errno = 0;
6317 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006318 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006319 if (errno == EINVAL)
6320 /* could be a path or name problem */
6321 posix_error();
6322 else
6323 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006324 }
Fred Drakec9680921999-12-13 16:37:25 +00006325 else
6326 result = PyInt_FromLong(limit);
6327 }
6328 return result;
6329}
6330#endif
6331
6332#ifdef HAVE_CONFSTR
6333static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006334#ifdef _CS_ARCHITECTURE
6335 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6336#endif
6337#ifdef _CS_HOSTNAME
6338 {"CS_HOSTNAME", _CS_HOSTNAME},
6339#endif
6340#ifdef _CS_HW_PROVIDER
6341 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6342#endif
6343#ifdef _CS_HW_SERIAL
6344 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6345#endif
6346#ifdef _CS_INITTAB_NAME
6347 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6348#endif
Fred Drakec9680921999-12-13 16:37:25 +00006349#ifdef _CS_LFS64_CFLAGS
6350 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6351#endif
6352#ifdef _CS_LFS64_LDFLAGS
6353 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6354#endif
6355#ifdef _CS_LFS64_LIBS
6356 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6357#endif
6358#ifdef _CS_LFS64_LINTFLAGS
6359 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6360#endif
6361#ifdef _CS_LFS_CFLAGS
6362 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6363#endif
6364#ifdef _CS_LFS_LDFLAGS
6365 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6366#endif
6367#ifdef _CS_LFS_LIBS
6368 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6369#endif
6370#ifdef _CS_LFS_LINTFLAGS
6371 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6372#endif
Fred Draked86ed291999-12-15 15:34:33 +00006373#ifdef _CS_MACHINE
6374 {"CS_MACHINE", _CS_MACHINE},
6375#endif
Fred Drakec9680921999-12-13 16:37:25 +00006376#ifdef _CS_PATH
6377 {"CS_PATH", _CS_PATH},
6378#endif
Fred Draked86ed291999-12-15 15:34:33 +00006379#ifdef _CS_RELEASE
6380 {"CS_RELEASE", _CS_RELEASE},
6381#endif
6382#ifdef _CS_SRPC_DOMAIN
6383 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6384#endif
6385#ifdef _CS_SYSNAME
6386 {"CS_SYSNAME", _CS_SYSNAME},
6387#endif
6388#ifdef _CS_VERSION
6389 {"CS_VERSION", _CS_VERSION},
6390#endif
Fred Drakec9680921999-12-13 16:37:25 +00006391#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6392 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6393#endif
6394#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6395 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6396#endif
6397#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6398 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6399#endif
6400#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6401 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6402#endif
6403#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6404 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6405#endif
6406#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6407 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6408#endif
6409#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6410 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6411#endif
6412#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6413 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6414#endif
6415#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6416 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6417#endif
6418#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6419 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6420#endif
6421#ifdef _CS_XBS5_LP64_OFF64_LIBS
6422 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6423#endif
6424#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6425 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6426#endif
6427#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6428 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6429#endif
6430#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6431 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6432#endif
6433#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6434 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6435#endif
6436#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6437 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6438#endif
Fred Draked86ed291999-12-15 15:34:33 +00006439#ifdef _MIPS_CS_AVAIL_PROCESSORS
6440 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6441#endif
6442#ifdef _MIPS_CS_BASE
6443 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6444#endif
6445#ifdef _MIPS_CS_HOSTID
6446 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6447#endif
6448#ifdef _MIPS_CS_HW_NAME
6449 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6450#endif
6451#ifdef _MIPS_CS_NUM_PROCESSORS
6452 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6453#endif
6454#ifdef _MIPS_CS_OSREL_MAJ
6455 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6456#endif
6457#ifdef _MIPS_CS_OSREL_MIN
6458 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6459#endif
6460#ifdef _MIPS_CS_OSREL_PATCH
6461 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6462#endif
6463#ifdef _MIPS_CS_OS_NAME
6464 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6465#endif
6466#ifdef _MIPS_CS_OS_PROVIDER
6467 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6468#endif
6469#ifdef _MIPS_CS_PROCESSORS
6470 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6471#endif
6472#ifdef _MIPS_CS_SERIAL
6473 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6474#endif
6475#ifdef _MIPS_CS_VENDOR
6476 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6477#endif
Fred Drakec9680921999-12-13 16:37:25 +00006478};
6479
6480static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006481conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006482{
6483 return conv_confname(arg, valuep, posix_constants_confstr,
6484 sizeof(posix_constants_confstr)
6485 / sizeof(struct constdef));
6486}
6487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006488PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006489"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006491
6492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006493posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006494{
6495 PyObject *result = NULL;
6496 int name;
6497 char buffer[64];
6498
6499 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6500 int len = confstr(name, buffer, sizeof(buffer));
6501
Fred Drakec9680921999-12-13 16:37:25 +00006502 errno = 0;
6503 if (len == 0) {
6504 if (errno != 0)
6505 posix_error();
6506 else
6507 result = PyString_FromString("");
6508 }
6509 else {
6510 if (len >= sizeof(buffer)) {
6511 result = PyString_FromStringAndSize(NULL, len);
6512 if (result != NULL)
6513 confstr(name, PyString_AS_STRING(result), len+1);
6514 }
6515 else
6516 result = PyString_FromString(buffer);
6517 }
6518 }
6519 return result;
6520}
6521#endif
6522
6523
6524#ifdef HAVE_SYSCONF
6525static struct constdef posix_constants_sysconf[] = {
6526#ifdef _SC_2_CHAR_TERM
6527 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6528#endif
6529#ifdef _SC_2_C_BIND
6530 {"SC_2_C_BIND", _SC_2_C_BIND},
6531#endif
6532#ifdef _SC_2_C_DEV
6533 {"SC_2_C_DEV", _SC_2_C_DEV},
6534#endif
6535#ifdef _SC_2_C_VERSION
6536 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6537#endif
6538#ifdef _SC_2_FORT_DEV
6539 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6540#endif
6541#ifdef _SC_2_FORT_RUN
6542 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6543#endif
6544#ifdef _SC_2_LOCALEDEF
6545 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6546#endif
6547#ifdef _SC_2_SW_DEV
6548 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6549#endif
6550#ifdef _SC_2_UPE
6551 {"SC_2_UPE", _SC_2_UPE},
6552#endif
6553#ifdef _SC_2_VERSION
6554 {"SC_2_VERSION", _SC_2_VERSION},
6555#endif
Fred Draked86ed291999-12-15 15:34:33 +00006556#ifdef _SC_ABI_ASYNCHRONOUS_IO
6557 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6558#endif
6559#ifdef _SC_ACL
6560 {"SC_ACL", _SC_ACL},
6561#endif
Fred Drakec9680921999-12-13 16:37:25 +00006562#ifdef _SC_AIO_LISTIO_MAX
6563 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6564#endif
Fred Drakec9680921999-12-13 16:37:25 +00006565#ifdef _SC_AIO_MAX
6566 {"SC_AIO_MAX", _SC_AIO_MAX},
6567#endif
6568#ifdef _SC_AIO_PRIO_DELTA_MAX
6569 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6570#endif
6571#ifdef _SC_ARG_MAX
6572 {"SC_ARG_MAX", _SC_ARG_MAX},
6573#endif
6574#ifdef _SC_ASYNCHRONOUS_IO
6575 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6576#endif
6577#ifdef _SC_ATEXIT_MAX
6578 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6579#endif
Fred Draked86ed291999-12-15 15:34:33 +00006580#ifdef _SC_AUDIT
6581 {"SC_AUDIT", _SC_AUDIT},
6582#endif
Fred Drakec9680921999-12-13 16:37:25 +00006583#ifdef _SC_AVPHYS_PAGES
6584 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6585#endif
6586#ifdef _SC_BC_BASE_MAX
6587 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6588#endif
6589#ifdef _SC_BC_DIM_MAX
6590 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6591#endif
6592#ifdef _SC_BC_SCALE_MAX
6593 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6594#endif
6595#ifdef _SC_BC_STRING_MAX
6596 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6597#endif
Fred Draked86ed291999-12-15 15:34:33 +00006598#ifdef _SC_CAP
6599 {"SC_CAP", _SC_CAP},
6600#endif
Fred Drakec9680921999-12-13 16:37:25 +00006601#ifdef _SC_CHARCLASS_NAME_MAX
6602 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6603#endif
6604#ifdef _SC_CHAR_BIT
6605 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6606#endif
6607#ifdef _SC_CHAR_MAX
6608 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6609#endif
6610#ifdef _SC_CHAR_MIN
6611 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6612#endif
6613#ifdef _SC_CHILD_MAX
6614 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6615#endif
6616#ifdef _SC_CLK_TCK
6617 {"SC_CLK_TCK", _SC_CLK_TCK},
6618#endif
6619#ifdef _SC_COHER_BLKSZ
6620 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6621#endif
6622#ifdef _SC_COLL_WEIGHTS_MAX
6623 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6624#endif
6625#ifdef _SC_DCACHE_ASSOC
6626 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6627#endif
6628#ifdef _SC_DCACHE_BLKSZ
6629 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6630#endif
6631#ifdef _SC_DCACHE_LINESZ
6632 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6633#endif
6634#ifdef _SC_DCACHE_SZ
6635 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6636#endif
6637#ifdef _SC_DCACHE_TBLKSZ
6638 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6639#endif
6640#ifdef _SC_DELAYTIMER_MAX
6641 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6642#endif
6643#ifdef _SC_EQUIV_CLASS_MAX
6644 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6645#endif
6646#ifdef _SC_EXPR_NEST_MAX
6647 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6648#endif
6649#ifdef _SC_FSYNC
6650 {"SC_FSYNC", _SC_FSYNC},
6651#endif
6652#ifdef _SC_GETGR_R_SIZE_MAX
6653 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6654#endif
6655#ifdef _SC_GETPW_R_SIZE_MAX
6656 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6657#endif
6658#ifdef _SC_ICACHE_ASSOC
6659 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6660#endif
6661#ifdef _SC_ICACHE_BLKSZ
6662 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6663#endif
6664#ifdef _SC_ICACHE_LINESZ
6665 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6666#endif
6667#ifdef _SC_ICACHE_SZ
6668 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6669#endif
Fred Draked86ed291999-12-15 15:34:33 +00006670#ifdef _SC_INF
6671 {"SC_INF", _SC_INF},
6672#endif
Fred Drakec9680921999-12-13 16:37:25 +00006673#ifdef _SC_INT_MAX
6674 {"SC_INT_MAX", _SC_INT_MAX},
6675#endif
6676#ifdef _SC_INT_MIN
6677 {"SC_INT_MIN", _SC_INT_MIN},
6678#endif
6679#ifdef _SC_IOV_MAX
6680 {"SC_IOV_MAX", _SC_IOV_MAX},
6681#endif
Fred Draked86ed291999-12-15 15:34:33 +00006682#ifdef _SC_IP_SECOPTS
6683 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6684#endif
Fred Drakec9680921999-12-13 16:37:25 +00006685#ifdef _SC_JOB_CONTROL
6686 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6687#endif
Fred Draked86ed291999-12-15 15:34:33 +00006688#ifdef _SC_KERN_POINTERS
6689 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6690#endif
6691#ifdef _SC_KERN_SIM
6692 {"SC_KERN_SIM", _SC_KERN_SIM},
6693#endif
Fred Drakec9680921999-12-13 16:37:25 +00006694#ifdef _SC_LINE_MAX
6695 {"SC_LINE_MAX", _SC_LINE_MAX},
6696#endif
6697#ifdef _SC_LOGIN_NAME_MAX
6698 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6699#endif
6700#ifdef _SC_LOGNAME_MAX
6701 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6702#endif
6703#ifdef _SC_LONG_BIT
6704 {"SC_LONG_BIT", _SC_LONG_BIT},
6705#endif
Fred Draked86ed291999-12-15 15:34:33 +00006706#ifdef _SC_MAC
6707 {"SC_MAC", _SC_MAC},
6708#endif
Fred Drakec9680921999-12-13 16:37:25 +00006709#ifdef _SC_MAPPED_FILES
6710 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6711#endif
6712#ifdef _SC_MAXPID
6713 {"SC_MAXPID", _SC_MAXPID},
6714#endif
6715#ifdef _SC_MB_LEN_MAX
6716 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6717#endif
6718#ifdef _SC_MEMLOCK
6719 {"SC_MEMLOCK", _SC_MEMLOCK},
6720#endif
6721#ifdef _SC_MEMLOCK_RANGE
6722 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6723#endif
6724#ifdef _SC_MEMORY_PROTECTION
6725 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6726#endif
6727#ifdef _SC_MESSAGE_PASSING
6728 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6729#endif
Fred Draked86ed291999-12-15 15:34:33 +00006730#ifdef _SC_MMAP_FIXED_ALIGNMENT
6731 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6732#endif
Fred Drakec9680921999-12-13 16:37:25 +00006733#ifdef _SC_MQ_OPEN_MAX
6734 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6735#endif
6736#ifdef _SC_MQ_PRIO_MAX
6737 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6738#endif
Fred Draked86ed291999-12-15 15:34:33 +00006739#ifdef _SC_NACLS_MAX
6740 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6741#endif
Fred Drakec9680921999-12-13 16:37:25 +00006742#ifdef _SC_NGROUPS_MAX
6743 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6744#endif
6745#ifdef _SC_NL_ARGMAX
6746 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6747#endif
6748#ifdef _SC_NL_LANGMAX
6749 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6750#endif
6751#ifdef _SC_NL_MSGMAX
6752 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6753#endif
6754#ifdef _SC_NL_NMAX
6755 {"SC_NL_NMAX", _SC_NL_NMAX},
6756#endif
6757#ifdef _SC_NL_SETMAX
6758 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6759#endif
6760#ifdef _SC_NL_TEXTMAX
6761 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6762#endif
6763#ifdef _SC_NPROCESSORS_CONF
6764 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6765#endif
6766#ifdef _SC_NPROCESSORS_ONLN
6767 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6768#endif
Fred Draked86ed291999-12-15 15:34:33 +00006769#ifdef _SC_NPROC_CONF
6770 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6771#endif
6772#ifdef _SC_NPROC_ONLN
6773 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6774#endif
Fred Drakec9680921999-12-13 16:37:25 +00006775#ifdef _SC_NZERO
6776 {"SC_NZERO", _SC_NZERO},
6777#endif
6778#ifdef _SC_OPEN_MAX
6779 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6780#endif
6781#ifdef _SC_PAGESIZE
6782 {"SC_PAGESIZE", _SC_PAGESIZE},
6783#endif
6784#ifdef _SC_PAGE_SIZE
6785 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6786#endif
6787#ifdef _SC_PASS_MAX
6788 {"SC_PASS_MAX", _SC_PASS_MAX},
6789#endif
6790#ifdef _SC_PHYS_PAGES
6791 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6792#endif
6793#ifdef _SC_PII
6794 {"SC_PII", _SC_PII},
6795#endif
6796#ifdef _SC_PII_INTERNET
6797 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6798#endif
6799#ifdef _SC_PII_INTERNET_DGRAM
6800 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6801#endif
6802#ifdef _SC_PII_INTERNET_STREAM
6803 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6804#endif
6805#ifdef _SC_PII_OSI
6806 {"SC_PII_OSI", _SC_PII_OSI},
6807#endif
6808#ifdef _SC_PII_OSI_CLTS
6809 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6810#endif
6811#ifdef _SC_PII_OSI_COTS
6812 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6813#endif
6814#ifdef _SC_PII_OSI_M
6815 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6816#endif
6817#ifdef _SC_PII_SOCKET
6818 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6819#endif
6820#ifdef _SC_PII_XTI
6821 {"SC_PII_XTI", _SC_PII_XTI},
6822#endif
6823#ifdef _SC_POLL
6824 {"SC_POLL", _SC_POLL},
6825#endif
6826#ifdef _SC_PRIORITIZED_IO
6827 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6828#endif
6829#ifdef _SC_PRIORITY_SCHEDULING
6830 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6831#endif
6832#ifdef _SC_REALTIME_SIGNALS
6833 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6834#endif
6835#ifdef _SC_RE_DUP_MAX
6836 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6837#endif
6838#ifdef _SC_RTSIG_MAX
6839 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6840#endif
6841#ifdef _SC_SAVED_IDS
6842 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6843#endif
6844#ifdef _SC_SCHAR_MAX
6845 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6846#endif
6847#ifdef _SC_SCHAR_MIN
6848 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6849#endif
6850#ifdef _SC_SELECT
6851 {"SC_SELECT", _SC_SELECT},
6852#endif
6853#ifdef _SC_SEMAPHORES
6854 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6855#endif
6856#ifdef _SC_SEM_NSEMS_MAX
6857 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6858#endif
6859#ifdef _SC_SEM_VALUE_MAX
6860 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6861#endif
6862#ifdef _SC_SHARED_MEMORY_OBJECTS
6863 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6864#endif
6865#ifdef _SC_SHRT_MAX
6866 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6867#endif
6868#ifdef _SC_SHRT_MIN
6869 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6870#endif
6871#ifdef _SC_SIGQUEUE_MAX
6872 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6873#endif
6874#ifdef _SC_SIGRT_MAX
6875 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6876#endif
6877#ifdef _SC_SIGRT_MIN
6878 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6879#endif
Fred Draked86ed291999-12-15 15:34:33 +00006880#ifdef _SC_SOFTPOWER
6881 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6882#endif
Fred Drakec9680921999-12-13 16:37:25 +00006883#ifdef _SC_SPLIT_CACHE
6884 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6885#endif
6886#ifdef _SC_SSIZE_MAX
6887 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6888#endif
6889#ifdef _SC_STACK_PROT
6890 {"SC_STACK_PROT", _SC_STACK_PROT},
6891#endif
6892#ifdef _SC_STREAM_MAX
6893 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6894#endif
6895#ifdef _SC_SYNCHRONIZED_IO
6896 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6897#endif
6898#ifdef _SC_THREADS
6899 {"SC_THREADS", _SC_THREADS},
6900#endif
6901#ifdef _SC_THREAD_ATTR_STACKADDR
6902 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6903#endif
6904#ifdef _SC_THREAD_ATTR_STACKSIZE
6905 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6906#endif
6907#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6908 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6909#endif
6910#ifdef _SC_THREAD_KEYS_MAX
6911 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6912#endif
6913#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6914 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6915#endif
6916#ifdef _SC_THREAD_PRIO_INHERIT
6917 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6918#endif
6919#ifdef _SC_THREAD_PRIO_PROTECT
6920 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6921#endif
6922#ifdef _SC_THREAD_PROCESS_SHARED
6923 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6924#endif
6925#ifdef _SC_THREAD_SAFE_FUNCTIONS
6926 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6927#endif
6928#ifdef _SC_THREAD_STACK_MIN
6929 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6930#endif
6931#ifdef _SC_THREAD_THREADS_MAX
6932 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6933#endif
6934#ifdef _SC_TIMERS
6935 {"SC_TIMERS", _SC_TIMERS},
6936#endif
6937#ifdef _SC_TIMER_MAX
6938 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6939#endif
6940#ifdef _SC_TTY_NAME_MAX
6941 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6942#endif
6943#ifdef _SC_TZNAME_MAX
6944 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6945#endif
6946#ifdef _SC_T_IOV_MAX
6947 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6948#endif
6949#ifdef _SC_UCHAR_MAX
6950 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6951#endif
6952#ifdef _SC_UINT_MAX
6953 {"SC_UINT_MAX", _SC_UINT_MAX},
6954#endif
6955#ifdef _SC_UIO_MAXIOV
6956 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6957#endif
6958#ifdef _SC_ULONG_MAX
6959 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6960#endif
6961#ifdef _SC_USHRT_MAX
6962 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6963#endif
6964#ifdef _SC_VERSION
6965 {"SC_VERSION", _SC_VERSION},
6966#endif
6967#ifdef _SC_WORD_BIT
6968 {"SC_WORD_BIT", _SC_WORD_BIT},
6969#endif
6970#ifdef _SC_XBS5_ILP32_OFF32
6971 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6972#endif
6973#ifdef _SC_XBS5_ILP32_OFFBIG
6974 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6975#endif
6976#ifdef _SC_XBS5_LP64_OFF64
6977 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6978#endif
6979#ifdef _SC_XBS5_LPBIG_OFFBIG
6980 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6981#endif
6982#ifdef _SC_XOPEN_CRYPT
6983 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6984#endif
6985#ifdef _SC_XOPEN_ENH_I18N
6986 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6987#endif
6988#ifdef _SC_XOPEN_LEGACY
6989 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6990#endif
6991#ifdef _SC_XOPEN_REALTIME
6992 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6993#endif
6994#ifdef _SC_XOPEN_REALTIME_THREADS
6995 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6996#endif
6997#ifdef _SC_XOPEN_SHM
6998 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6999#endif
7000#ifdef _SC_XOPEN_UNIX
7001 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7002#endif
7003#ifdef _SC_XOPEN_VERSION
7004 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7005#endif
7006#ifdef _SC_XOPEN_XCU_VERSION
7007 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7008#endif
7009#ifdef _SC_XOPEN_XPG2
7010 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7011#endif
7012#ifdef _SC_XOPEN_XPG3
7013 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7014#endif
7015#ifdef _SC_XOPEN_XPG4
7016 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7017#endif
7018};
7019
7020static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007021conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007022{
7023 return conv_confname(arg, valuep, posix_constants_sysconf,
7024 sizeof(posix_constants_sysconf)
7025 / sizeof(struct constdef));
7026}
7027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007028PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007029"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007030Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007031
7032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007033posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007034{
7035 PyObject *result = NULL;
7036 int name;
7037
7038 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7039 int value;
7040
7041 errno = 0;
7042 value = sysconf(name);
7043 if (value == -1 && errno != 0)
7044 posix_error();
7045 else
7046 result = PyInt_FromLong(value);
7047 }
7048 return result;
7049}
7050#endif
7051
7052
Fred Drakebec628d1999-12-15 18:31:10 +00007053/* This code is used to ensure that the tables of configuration value names
7054 * are in sorted order as required by conv_confname(), and also to build the
7055 * the exported dictionaries that are used to publish information about the
7056 * names available on the host platform.
7057 *
7058 * Sorting the table at runtime ensures that the table is properly ordered
7059 * when used, even for platforms we're not able to test on. It also makes
7060 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007061 */
Fred Drakebec628d1999-12-15 18:31:10 +00007062
7063static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007064cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007065{
7066 const struct constdef *c1 =
7067 (const struct constdef *) v1;
7068 const struct constdef *c2 =
7069 (const struct constdef *) v2;
7070
7071 return strcmp(c1->name, c2->name);
7072}
7073
7074static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007075setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007076 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007077{
Fred Drakebec628d1999-12-15 18:31:10 +00007078 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007079 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007080
7081 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7082 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007083 if (d == NULL)
7084 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007085
Barry Warsaw3155db32000-04-13 15:20:40 +00007086 for (i=0; i < tablesize; ++i) {
7087 PyObject *o = PyInt_FromLong(table[i].value);
7088 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7089 Py_XDECREF(o);
7090 Py_DECREF(d);
7091 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007092 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007093 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007094 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007095 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007096}
7097
Fred Drakebec628d1999-12-15 18:31:10 +00007098/* Return -1 on failure, 0 on success. */
7099static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007100setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007101{
7102#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007103 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007104 sizeof(posix_constants_pathconf)
7105 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007106 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007107 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007108#endif
7109#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007110 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007111 sizeof(posix_constants_confstr)
7112 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007113 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007114 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007115#endif
7116#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007117 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007118 sizeof(posix_constants_sysconf)
7119 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007120 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007121 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007122#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007123 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007124}
Fred Draked86ed291999-12-15 15:34:33 +00007125
7126
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007128"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007129Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007130in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007131
7132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007133posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134{
7135 if (!PyArg_ParseTuple(args, ":abort"))
7136 return NULL;
7137 abort();
7138 /*NOTREACHED*/
7139 Py_FatalError("abort() called from Python code didn't abort!");
7140 return NULL;
7141}
Fred Drakebec628d1999-12-15 18:31:10 +00007142
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007143#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007144PyDoc_STRVAR(win32_startfile__doc__,
7145"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007146\n\
7147This acts like double-clicking the file in Explorer, or giving the file\n\
7148name as an argument to the DOS \"start\" command: the file is opened\n\
7149with whatever application (if any) its extension is associated.\n\
7150\n\
7151startfile returns as soon as the associated application is launched.\n\
7152There is no option to wait for the application to close, and no way\n\
7153to retrieve the application's exit status.\n\
7154\n\
7155The filepath is relative to the current directory. If you want to use\n\
7156an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007157the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007158
7159static PyObject *
7160win32_startfile(PyObject *self, PyObject *args)
7161{
7162 char *filepath;
7163 HINSTANCE rc;
7164 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7165 return NULL;
7166 Py_BEGIN_ALLOW_THREADS
7167 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7168 Py_END_ALLOW_THREADS
7169 if (rc <= (HINSTANCE)32)
7170 return win32_error("startfile", filepath);
7171 Py_INCREF(Py_None);
7172 return Py_None;
7173}
7174#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007175
Martin v. Löwis438b5342002-12-27 10:16:42 +00007176#ifdef HAVE_GETLOADAVG
7177PyDoc_STRVAR(posix_getloadavg__doc__,
7178"getloadavg() -> (float, float, float)\n\n\
7179Return the number of processes in the system run queue averaged over\n\
7180the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7181was unobtainable");
7182
7183static PyObject *
7184posix_getloadavg(PyObject *self, PyObject *args)
7185{
7186 double loadavg[3];
7187 if (!PyArg_ParseTuple(args, ":getloadavg"))
7188 return NULL;
7189 if (getloadavg(loadavg, 3)!=3) {
7190 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7191 return NULL;
7192 } else
7193 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7194}
7195#endif
7196
7197
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198static PyMethodDef posix_methods[] = {
7199 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7200#ifdef HAVE_TTYNAME
7201 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7202#endif
7203 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7204 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007205#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007207#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007208#ifdef HAVE_LCHOWN
7209 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7210#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007211#ifdef HAVE_CHROOT
7212 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007214#ifdef HAVE_CTERMID
7215 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
7216#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007217#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007218 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007219#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007220 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007221#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007222#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007223#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007225#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007226 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7227 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7228 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007229#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007230 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007231#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007232#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007233 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007234#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007235 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7236 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7237 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007238 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007239#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007240 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007241#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007242#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007243 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007244#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007245 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007246#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007247 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007248#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7250 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7251 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007252#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007253 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007254#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007255 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007256#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007257 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7258 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007259#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007260#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007261 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7262 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007263#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007264#ifdef HAVE_FORK1
7265 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
7266#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007267#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007268 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007269#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007270#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007271 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007272#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007273#ifdef HAVE_FORKPTY
7274 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
7275#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007276#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007277 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007278#endif /* HAVE_GETEGID */
7279#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007280 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007281#endif /* HAVE_GETEUID */
7282#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007283 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007284#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007285#ifdef HAVE_GETGROUPS
7286 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
7287#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007288 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007289#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007290 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007291#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007292#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007293 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007294#endif /* HAVE_GETPPID */
7295#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007296 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007297#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007298#ifdef HAVE_GETLOGIN
7299 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
7300#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007301#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007302 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007303#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007304#ifdef HAVE_KILLPG
7305 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7306#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007307#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007308 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007309#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007310#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007311 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007312#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007313 {"popen2", win32_popen2, METH_VARARGS},
7314 {"popen3", win32_popen3, METH_VARARGS},
7315 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007316 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007317#else
7318#if defined(PYOS_OS2) && defined(PYCC_GCC)
7319 {"popen2", os2emx_popen2, METH_VARARGS},
7320 {"popen3", os2emx_popen3, METH_VARARGS},
7321 {"popen4", os2emx_popen4, METH_VARARGS},
7322#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007323#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007324#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007325#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007326 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007327#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007328#ifdef HAVE_SETEUID
7329 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7330#endif /* HAVE_SETEUID */
7331#ifdef HAVE_SETEGID
7332 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7333#endif /* HAVE_SETEGID */
7334#ifdef HAVE_SETREUID
7335 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7336#endif /* HAVE_SETREUID */
7337#ifdef HAVE_SETREGID
7338 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7339#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007340#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007341 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007342#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007343#ifdef HAVE_SETGROUPS
7344 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7345#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007346#ifdef HAVE_GETPGID
7347 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7348#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007349#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007350 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007351#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007352#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007353 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007354#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007355#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007356 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007357#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007358#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007359 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007360#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007361#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007362 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007363#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007364#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007366#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007367#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007368 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007369#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007370 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7371 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7372 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7373 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7374 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7375 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7376 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7377 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7378 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007379 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007380#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007381 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007382#endif
7383#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007384 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007385#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007386#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007387 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007389#ifdef HAVE_DEVICE_MACROS
7390 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7391 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7392 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7393#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007394#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007395 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007396#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007397#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007398 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007399#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007400#ifdef HAVE_UNSETENV
7401 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7402#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007403#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007404 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007405#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007406#ifdef HAVE_FCHDIR
7407 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7408#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007409#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007410 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007411#endif
7412#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007413 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007414#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007415#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007416#ifdef WCOREDUMP
7417 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7418#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007419#ifdef WIFCONTINUED
7420 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7421#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007422#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007424#endif /* WIFSTOPPED */
7425#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007426 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007427#endif /* WIFSIGNALED */
7428#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007429 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007430#endif /* WIFEXITED */
7431#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007432 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007433#endif /* WEXITSTATUS */
7434#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007435 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007436#endif /* WTERMSIG */
7437#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007438 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007439#endif /* WSTOPSIG */
7440#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007441#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007442 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007443#endif
7444#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007445 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007446#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007447#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007448 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7449#endif
7450#ifdef HAVE_TEMPNAM
7451 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7452#endif
7453#ifdef HAVE_TMPNAM
7454 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7455#endif
Fred Drakec9680921999-12-13 16:37:25 +00007456#ifdef HAVE_CONFSTR
7457 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7458#endif
7459#ifdef HAVE_SYSCONF
7460 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7461#endif
7462#ifdef HAVE_FPATHCONF
7463 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7464#endif
7465#ifdef HAVE_PATHCONF
7466 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7467#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007468 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007469#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007470 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7471#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007472#ifdef HAVE_GETLOADAVG
7473 {"getloadavg", posix_getloadavg, METH_VARARGS, posix_getloadavg__doc__},
7474#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007475 {NULL, NULL} /* Sentinel */
7476};
7477
7478
Barry Warsaw4a342091996-12-19 23:50:02 +00007479static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007480ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007481{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007482 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007483}
7484
Guido van Rossumd48f2521997-12-05 22:19:34 +00007485#if defined(PYOS_OS2)
7486/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007487static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007488{
7489 APIRET rc;
7490 ULONG values[QSV_MAX+1];
7491 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007492 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007493
7494 Py_BEGIN_ALLOW_THREADS
7495 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7496 Py_END_ALLOW_THREADS
7497
7498 if (rc != NO_ERROR) {
7499 os2_error(rc);
7500 return -1;
7501 }
7502
Fred Drake4d1e64b2002-04-15 19:40:07 +00007503 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7504 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7505 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7506 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7507 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7508 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7509 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007510
7511 switch (values[QSV_VERSION_MINOR]) {
7512 case 0: ver = "2.00"; break;
7513 case 10: ver = "2.10"; break;
7514 case 11: ver = "2.11"; break;
7515 case 30: ver = "3.00"; break;
7516 case 40: ver = "4.00"; break;
7517 case 50: ver = "5.00"; break;
7518 default:
Tim Peters885d4572001-11-28 20:27:42 +00007519 PyOS_snprintf(tmp, sizeof(tmp),
7520 "%d-%d", values[QSV_VERSION_MAJOR],
7521 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007522 ver = &tmp[0];
7523 }
7524
7525 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007526 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007527 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007528
7529 /* Add Indicator of Which Drive was Used to Boot the System */
7530 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7531 tmp[1] = ':';
7532 tmp[2] = '\0';
7533
Fred Drake4d1e64b2002-04-15 19:40:07 +00007534 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007535}
7536#endif
7537
Barry Warsaw4a342091996-12-19 23:50:02 +00007538static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007539all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007540{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007541#ifdef F_OK
7542 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007543#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007544#ifdef R_OK
7545 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007546#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007547#ifdef W_OK
7548 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007549#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007550#ifdef X_OK
7551 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007552#endif
Fred Drakec9680921999-12-13 16:37:25 +00007553#ifdef NGROUPS_MAX
7554 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7555#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007556#ifdef TMP_MAX
7557 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7558#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007559#ifdef WCONTINUED
7560 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7561#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007562#ifdef WNOHANG
7563 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007564#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007565#ifdef WUNTRACED
7566 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7567#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007568#ifdef O_RDONLY
7569 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7570#endif
7571#ifdef O_WRONLY
7572 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7573#endif
7574#ifdef O_RDWR
7575 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7576#endif
7577#ifdef O_NDELAY
7578 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7579#endif
7580#ifdef O_NONBLOCK
7581 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7582#endif
7583#ifdef O_APPEND
7584 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7585#endif
7586#ifdef O_DSYNC
7587 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7588#endif
7589#ifdef O_RSYNC
7590 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7591#endif
7592#ifdef O_SYNC
7593 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7594#endif
7595#ifdef O_NOCTTY
7596 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7597#endif
7598#ifdef O_CREAT
7599 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7600#endif
7601#ifdef O_EXCL
7602 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7603#endif
7604#ifdef O_TRUNC
7605 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7606#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007607#ifdef O_BINARY
7608 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7609#endif
7610#ifdef O_TEXT
7611 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7612#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007613#ifdef O_LARGEFILE
7614 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7615#endif
7616
Tim Peters5aa91602002-01-30 05:46:57 +00007617/* MS Windows */
7618#ifdef O_NOINHERIT
7619 /* Don't inherit in child processes. */
7620 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7621#endif
7622#ifdef _O_SHORT_LIVED
7623 /* Optimize for short life (keep in memory). */
7624 /* MS forgot to define this one with a non-underscore form too. */
7625 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7626#endif
7627#ifdef O_TEMPORARY
7628 /* Automatically delete when last handle is closed. */
7629 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7630#endif
7631#ifdef O_RANDOM
7632 /* Optimize for random access. */
7633 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7634#endif
7635#ifdef O_SEQUENTIAL
7636 /* Optimize for sequential access. */
7637 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7638#endif
7639
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007640/* GNU extensions. */
7641#ifdef O_DIRECT
7642 /* Direct disk access. */
7643 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7644#endif
7645#ifdef O_DIRECTORY
7646 /* Must be a directory. */
7647 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7648#endif
7649#ifdef O_NOFOLLOW
7650 /* Do not follow links. */
7651 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7652#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007653
Guido van Rossum246bc171999-02-01 23:54:31 +00007654#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007655#if defined(PYOS_OS2) && defined(PYCC_GCC)
7656 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7657 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7658 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7659 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7660 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7661 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7662 if (ins(d, "P_PM", (long)P_PM)) return -1;
7663 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7664 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7665 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7666 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7667 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7668 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7669 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7670 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7671 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7672 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7673 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7674 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7675 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7676#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007677 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7678 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7679 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7680 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7681 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007682#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007683#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007684
Guido van Rossumd48f2521997-12-05 22:19:34 +00007685#if defined(PYOS_OS2)
7686 if (insertvalues(d)) return -1;
7687#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007688 return 0;
7689}
7690
7691
Tim Peters5aa91602002-01-30 05:46:57 +00007692#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007693#define INITFUNC initnt
7694#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007695
7696#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007697#define INITFUNC initos2
7698#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007699
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007700#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007701#define INITFUNC initposix
7702#define MODNAME "posix"
7703#endif
7704
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007705PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007706INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007708 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007709
Fred Drake4d1e64b2002-04-15 19:40:07 +00007710 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007711 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007712 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007713
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007714 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007716 Py_XINCREF(v);
7717 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007718 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007719 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007720
Fred Drake4d1e64b2002-04-15 19:40:07 +00007721 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007722 return;
7723
Fred Drake4d1e64b2002-04-15 19:40:07 +00007724 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007725 return;
7726
Fred Drake4d1e64b2002-04-15 19:40:07 +00007727 Py_INCREF(PyExc_OSError);
7728 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007729
Guido van Rossumb3d39562000-01-31 18:41:26 +00007730#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007731 if (posix_putenv_garbage == NULL)
7732 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007733#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007734
Guido van Rossum14648392001-12-08 18:02:58 +00007735 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007736 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7737 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7738 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007739 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007740 structseq_new = StatResultType.tp_new;
7741 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007742 Py_INCREF((PyObject*) &StatResultType);
7743 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007744
Guido van Rossum14648392001-12-08 18:02:58 +00007745 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007746 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007747 Py_INCREF((PyObject*) &StatVFSResultType);
7748 PyModule_AddObject(m, "statvfs_result",
7749 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007750}