blob: 713729a8af71c0fc7f7f5e10a2e6a8da4d50746c [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
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000096/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000097#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000098#include <process.h>
99#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000100#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_OPENDIR 1
103#define HAVE_SYSTEM 1
104#if defined(__OS2__)
105#define HAVE_EXECV 1
106#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000107#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#include <process.h>
109#else
110#ifdef __BORLANDC__ /* Borland compiler */
111#define HAVE_EXECV 1
112#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#define HAVE_OPENDIR 1
114#define HAVE_PIPE 1
115#define HAVE_POPEN 1
116#define HAVE_SYSTEM 1
117#define HAVE_WAIT 1
118#else
119#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000120#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000121#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000122#define HAVE_EXECV 1
123#define HAVE_PIPE 1
124#define HAVE_POPEN 1
125#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000126#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000127#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000128#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
129/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#else /* all other compilers */
131/* Unix functions that the configure script doesn't check for */
132#define HAVE_EXECV 1
133#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000134#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
135#define HAVE_FORK1 1
136#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#define HAVE_GETCWD 1
138#define HAVE_GETEGID 1
139#define HAVE_GETEUID 1
140#define HAVE_GETGID 1
141#define HAVE_GETPPID 1
142#define HAVE_GETUID 1
143#define HAVE_KILL 1
144#define HAVE_OPENDIR 1
145#define HAVE_PIPE 1
146#define HAVE_POPEN 1
147#define HAVE_SYSTEM 1
148#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000149#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000150#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#endif /* _MSC_VER */
152#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000153#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000155
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000157
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000158#if defined(sun) && !defined(__SVR4)
159/* SunOS 4.1.4 doesn't have prototypes for these: */
160extern int rename(const char *, const char *);
161extern int pclose(FILE *);
162extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000163extern int fsync(int);
164extern int lstat(const char *, struct stat *);
165extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000166#endif
167
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000168#if defined(__sgi)&&_COMPILER_VERSION>=700
169/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
170 (default) */
171extern char *ctermid_r(char *);
172#endif
173
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000174#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000178#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
184#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000185extern int chdir(char *);
186extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000187#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000188extern int chdir(const char *);
189extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000190#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000191#ifdef __BORLANDC__
192extern int chmod(const char *, int);
193#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000195#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int chown(const char *, uid_t, gid_t);
197extern char *getcwd(char *, int);
198extern char *strerror(int);
199extern int link(const char *, const char *);
200extern int rename(const char *, const char *);
201extern int stat(const char *, struct stat *);
202extern int unlink(const char *);
203extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000206#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000209#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_UTIME_H
215#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000218#ifdef HAVE_SYS_UTIME_H
219#include <sys/utime.h>
220#define HAVE_UTIME_H /* pretend we do for the rest of this file */
221#endif /* HAVE_SYS_UTIME_H */
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_SYS_TIMES_H
224#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
227#ifdef HAVE_SYS_PARAM_H
228#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_UTSNAME_H
232#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#define NAMLEN(dirent) strlen((dirent)->d_name)
238#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000239#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#include <direct.h>
241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#endif
252#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#endif
255#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000257#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <direct.h>
259#include <io.h>
260#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000261#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000262#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000264#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000265#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000266#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000267#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossumd48f2521997-12-05 22:19:34 +0000269#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000271#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272
Tim Petersbc2e10e2002-03-03 23:17:02 +0000273#ifndef MAXPATHLEN
274#define MAXPATHLEN 1024
275#endif /* MAXPATHLEN */
276
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000277#ifdef UNION_WAIT
278/* Emulate some macros on systems that have a union instead of macros */
279
280#ifndef WIFEXITED
281#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
282#endif
283
284#ifndef WEXITSTATUS
285#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
286#endif
287
288#ifndef WTERMSIG
289#define WTERMSIG(u_wait) ((u_wait).w_termsig)
290#endif
291
292#endif /* UNION_WAIT */
293
Greg Wardb48bc172000-03-01 21:51:56 +0000294/* Don't use the "_r" form if we don't need it (also, won't have a
295 prototype for it, at least on Solaris -- maybe others as well?). */
296#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
297#define USE_CTERMID_R
298#endif
299
300#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
301#define USE_TMPNAM_R
302#endif
303
Fred Drake699f3522000-06-29 21:12:41 +0000304/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000305#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000306#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000307# define STAT _stati64
308# define FSTAT _fstati64
309# define STRUCT_STAT struct _stati64
310#else
311# define STAT stat
312# define FSTAT fstat
313# define STRUCT_STAT struct stat
314#endif
315
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000316#if defined(MAJOR_IN_MKDEV)
317#include <sys/mkdev.h>
318#else
319#if defined(MAJOR_IN_SYSMACROS)
320#include <sys/sysmacros.h>
321#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000322#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
323#include <sys/mkdev.h>
324#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000325#endif
Fred Drake699f3522000-06-29 21:12:41 +0000326
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000328#ifdef WITH_NEXT_FRAMEWORK
329/* On Darwin/MacOSX a shared library or framework has no access to
330** environ directly, we must obtain it with _NSGetEnviron().
331*/
332#include <crt_externs.h>
333static char **environ;
334#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000336#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000338#if defined(__VMS)
339static char psxmod_gt_psxpath[1026];
340
341static int
342psxmod_from_vms_action (char *spec)
343{
344 (void)strcpy(psxmod_gt_psxpath, spec);
345 return 1;
346}
347
348/* Return a dictionary corresponding to the VMS 'environment table' */
349static char* at_home = "HOME";
350static char* at_path = "PATH";
351
352static char psxmod_t_command [] = "SYS$COMMAND";
353/* add some values to provide a similar environment like POSIX */
354void
355psmmod_add_posix_env(PyObject *d)
356{
357 /* -------------------- */
358 struct dsc$descriptor_s r_device_name;
359 long l_devbufsiz;
360 long l_tt_page;
361 long l_item_code;
362 long l_status;
363 PyObject *o;
364 struct dsc$descriptor_s r_resultant_string;
365 char t_resultant_string[13]; /* enough space for username (12)+ '\0' */
366 char *at_resultant_string;
367 short int w_resultant_length;
368
369 /* set up string descriptor */
370 r_device_name.dsc$w_length = strlen(psxmod_t_command);
371 r_device_name.dsc$b_dtype = DSC$K_DTYPE_T;
372 r_device_name.dsc$b_class = DSC$K_CLASS_S;
373 r_device_name.dsc$a_pointer = &psxmod_t_command[0];
374
375 /* -------------------- */
376 /* COLUMNS = $getdvi("SYS$COMMAND","DEVBUFSIZ") */
377 l_item_code = DVI$_DEVBUFSIZ;
378 l_status = lib$getdvi(&l_item_code,
379 0, /* [channel] */
380 &r_device_name,
381 &l_devbufsiz, /* integer-value */
382 0, /* resultant_string */
383 0); /* resultant_length */
384 if (l_status == SS$_NORMAL) {
385 /* create a string object here to comply with POSIX */
386
387 /* set up string descriptor */
388 r_resultant_string.dsc$w_length =
389 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
390 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
391 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
392 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
393
394 /* Convert Signed Integer to Decimal Text */
395 l_status = ots$cvt_l_ti(&l_devbufsiz, &r_resultant_string, 1,
396 4, 0);
397 if (l_status == SS$_NORMAL) {
398 /* terminate string for 'C'-style */
399 t_resultant_string[sizeof(t_resultant_string)-1] = '\0';
400 /* string appears as: ' value' -- skip ' ' */
401 at_resultant_string = &t_resultant_string[0];
402 while ((*at_resultant_string == ' ' ) &&
403 (*at_resultant_string != '\0')) {
404 at_resultant_string++; /* skip prefix spaces */
405 }
406
407 o = Py_BuildValue("s", at_resultant_string);
408 if (o != NULL) {
409 (void) PyDict_SetItemString(d, "COLUMNS", o);
410 Py_DECREF(o);
411 }
412 } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */
413 } /* (l_status = lib$getdvi(DVI$_DEVBUFSIZ) == SS$_NORMAL) */
414 /* LINES = $getdvi("SYS$COMMAND","TT_PAGE") */
415 l_item_code = DVI$_TT_PAGE;
416 l_status = lib$getdvi(&l_item_code,
417 0, /* [channel] */
418 &r_device_name,
419 &l_tt_page, /* integer-value */
420 0, /* resultant_string */
421 0); /* resultant_length */
422 if (l_status == SS$_NORMAL) {
423 /* create a string object here to comply with POSIX */
424
425 /* set up string descriptor */
426 r_resultant_string.dsc$w_length =
427 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
428 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
429 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
430 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
431
432 /* Convert Signed Integer to Decimal Text */
433 l_status = ots$cvt_l_ti(&l_tt_page, &r_resultant_string,
434 1, 4, 0);
435 if (l_status == SS$_NORMAL) {
436 /* terminate string for 'C'-style */
437 t_resultant_string[sizeof(t_resultant_string)-1] = '\0';
438 /* string appears as: ' value' -- skip ' ' */
439 at_resultant_string = &t_resultant_string[0];
440 while ((*at_resultant_string == ' ' ) &&
441 (*at_resultant_string != '\0')) {
442 at_resultant_string++; /* skip prefix spaces */
443 }
444
445 o = Py_BuildValue("s", at_resultant_string);
446 if (o != NULL) {
447 (void)PyDict_SetItemString(d, "LINES", o);
448 Py_DECREF(o);
449 }
450 } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */
451 } /* (l_status = lib$getdvi(DVI$_TT_PAGE) == SS$_NORMAL) */
452 /* else -- ignore error */
453
454 /* LOGNAME = $getjpi(0,"USERNAME") */
455 l_item_code = JPI$_USERNAME;
456
457 /* set up string descriptor */
458 r_resultant_string.dsc$w_length =
459 (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */
460 r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T;
461 r_resultant_string.dsc$b_class = DSC$K_CLASS_S;
462 r_resultant_string.dsc$a_pointer = &t_resultant_string[0];
463
464 l_status = lib$getjpi(&l_item_code, 0, 0, 0,
465 &r_resultant_string, &w_resultant_length);
466 if (l_status == SS$_NORMAL){
467 t_resultant_string[w_resultant_length] = '\0';
468
469 /* remove any trailing spaces by replacing 1st one with '\0' */
470 at_resultant_string = &t_resultant_string[0];
471 while ((*at_resultant_string != ' ' ) &&
472 (*at_resultant_string != '\0')) {
473 /* lowercase for compatibility with POSIX */
474 *at_resultant_string = tolower(*at_resultant_string);
475 at_resultant_string++; /* skip non-blank */
476 }
477 *at_resultant_string = '\0'; /* terminate */
478
479 o = Py_BuildValue("s", &t_resultant_string[0]);
480 if (o != NULL) {
481 (void) PyDict_SetItemString(d, "LOGNAME", o);
482 (void) PyDict_SetItemString(d, "USERNAME", o);
483 Py_DECREF(o);
484 }
485 } /* (l_status == SS$_NORMAL) */
486
487 /* OS = "OpenVMS" */
488 o = PyString_FromString ("OpenVMS");
489 if (o != NULL) {
490 (void)PyDict_SetItemString(d, "OS", o);
491 Py_DECREF(o);
492 }
493}
494
495/* @@ posix env:
496COLUMNS=80 $ write sys$output f$getdvi("SYS$COMMAND","DEVBUFSIZ")
497LINES=47 $ write sys$output f$getdvi("SYS$COMMAND","TT_PAGE")
498LOGNAME=zessin $ write sys$output f$edit(f$getjpi(0,"username"), -
499 "collapse,lowercase")
500OS=OpenVMS
501PS1=HERE $
502
503TZ=CET-1:00CET DST,M3.5.0/2:00,M10.5.0/3:00
504 $ write sys$output f$trnlnm("POSIX$DEFAULT_TZ")
505 "CET-1:00CET DST-2:00,M3.5.0/2:00,M10.5.0/3:00"
506 $ write sys$output f$trnlnm("UCX$TZ")
507 "MET-1MET_DST-2,M3.5.0/2,M10.5.0/3"
508PAGER=more
509TERM=vt300_series
510SHELL=/bin/sh
511HOME=/dka100/user/zessin
512_=/bin/env
513
514>>> for v in os.environ.items():
515... print v
516...
517('HOME', '/user_here/zessin')
518('COLUMNS', '80')
519('LINES', '24')
520('PATH', '/python_disk/python/python-1_5_2/vms')
521('OS', 'OpenVMS')
522('USER', 'ZESSIN')
523('LOGNAME', 'zessin')
524('TERM', 'vt300-80')
525('USERNAME', 'zessin')
526>>>
527*/
528#endif /* __VMS */
529
Barry Warsaw53699e91996-12-10 23:23:01 +0000530static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000531convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532{
Barry Warsaw53699e91996-12-10 23:23:01 +0000533 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000534 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000535 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 if (d == NULL)
537 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000538#ifdef WITH_NEXT_FRAMEWORK
539 if (environ == NULL)
540 environ = *_NSGetEnviron();
541#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542 if (environ == NULL)
543 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000544 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000546 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000547 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548 char *p = strchr(*e, '=');
549 if (p == NULL)
550 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000551 k = PyString_FromStringAndSize(*e, (int)(p-*e));
552 if (k == NULL) {
553 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000555 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000556#if defined(__VMS)
557 if ((strncmp(at_home, *e, sizeof(at_home)) == 0) ||
558 (strncmp(at_path, *e, sizeof(at_path)) == 0)) {
559 (void)shell$from_vms(p+1, psxmod_from_vms_action, 0);
560 /* 0 = no wildcard expansion */
561 v = PyString_FromString(psxmod_gt_psxpath);
562 }
563 else {
564 v = PyString_FromString(p+1);
565 }
566#else
Guido van Rossum6a619f41999-08-03 19:41:10 +0000567 v = PyString_FromString(p+1);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000568#endif
Guido van Rossum6a619f41999-08-03 19:41:10 +0000569 if (v == NULL) {
570 PyErr_Clear();
571 Py_DECREF(k);
572 continue;
573 }
574 if (PyDict_GetItem(d, k) == NULL) {
575 if (PyDict_SetItem(d, k, v) != 0)
576 PyErr_Clear();
577 }
578 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000579 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000580 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000581#if defined(__VMS)
582 psmmod_add_posix_env(d);
583#endif /* defined(__VMS) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000584#if defined(PYOS_OS2)
585 {
586 APIRET rc;
587 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
588
589 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000590 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000591 PyObject *v = PyString_FromString(buffer);
592 PyDict_SetItemString(d, "BEGINLIBPATH", v);
593 Py_DECREF(v);
594 }
595 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
596 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
597 PyObject *v = PyString_FromString(buffer);
598 PyDict_SetItemString(d, "ENDLIBPATH", v);
599 Py_DECREF(v);
600 }
601 }
602#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603 return d;
604}
605
606
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000607/* Set a POSIX-specific error from errno, and return NULL */
608
Barry Warsawd58d7641998-07-23 16:14:40 +0000609static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000610posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000611{
Barry Warsawca74da41999-02-09 19:31:45 +0000612 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613}
Barry Warsawd58d7641998-07-23 16:14:40 +0000614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000615posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000616{
Barry Warsawca74da41999-02-09 19:31:45 +0000617 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000618}
619
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000620#ifdef Py_WIN_WIDE_FILENAMES
621static PyObject *
622posix_error_with_unicode_filename(Py_UNICODE* name)
623{
624 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
625}
626#endif /* Py_WIN_WIDE_FILENAMES */
627
628
Mark Hammondef8b6542001-05-13 08:04:26 +0000629static PyObject *
630posix_error_with_allocated_filename(char* name)
631{
632 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
633 PyMem_Free(name);
634 return rc;
635}
636
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000637#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000638static PyObject *
639win32_error(char* function, char* filename)
640{
Mark Hammond33a6da92000-08-15 00:46:38 +0000641 /* XXX We should pass the function name along in the future.
642 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000643 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000644 Windows error object, which is non-trivial.
645 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000646 errno = GetLastError();
647 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000648 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000649 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000650 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000651}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000652
653#ifdef Py_WIN_WIDE_FILENAMES
654static PyObject *
655win32_error_unicode(char* function, Py_UNICODE* filename)
656{
657 /* XXX - see win32_error for comments on 'function' */
658 errno = GetLastError();
659 if (filename)
660 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
661 else
662 return PyErr_SetFromWindowsErr(errno);
663}
664
665static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
666{
667 /* XXX Perhaps we should make this API an alias of
668 PyObject_Unicode() instead ?! */
669 if (PyUnicode_CheckExact(obj)) {
670 Py_INCREF(obj);
671 return obj;
672 }
673 if (PyUnicode_Check(obj)) {
674 /* For a Unicode subtype that's not a Unicode object,
675 return a true Unicode object with the same data. */
676 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
677 PyUnicode_GET_SIZE(obj));
678 }
679 return PyUnicode_FromEncodedObject(obj,
680 Py_FileSystemDefaultEncoding,
681 "strict");
682}
683
684#endif /* Py_WIN_WIDE_FILENAMES */
685
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000686#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687
Guido van Rossumd48f2521997-12-05 22:19:34 +0000688#if defined(PYOS_OS2)
689/**********************************************************************
690 * Helper Function to Trim and Format OS/2 Messages
691 **********************************************************************/
692 static void
693os2_formatmsg(char *msgbuf, int msglen, char *reason)
694{
695 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
696
697 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
698 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
699
700 while (lastc > msgbuf && isspace(*lastc))
701 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
702 }
703
704 /* Add Optional Reason Text */
705 if (reason) {
706 strcat(msgbuf, " : ");
707 strcat(msgbuf, reason);
708 }
709}
710
711/**********************************************************************
712 * Decode an OS/2 Operating System Error Code
713 *
714 * A convenience function to lookup an OS/2 error code and return a
715 * text message we can use to raise a Python exception.
716 *
717 * Notes:
718 * The messages for errors returned from the OS/2 kernel reside in
719 * the file OSO001.MSG in the \OS2 directory hierarchy.
720 *
721 **********************************************************************/
722 static char *
723os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
724{
725 APIRET rc;
726 ULONG msglen;
727
728 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
729 Py_BEGIN_ALLOW_THREADS
730 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
731 errorcode, "oso001.msg", &msglen);
732 Py_END_ALLOW_THREADS
733
734 if (rc == NO_ERROR)
735 os2_formatmsg(msgbuf, msglen, reason);
736 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000737 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000738 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000739
740 return msgbuf;
741}
742
743/* Set an OS/2-specific error and return NULL. OS/2 kernel
744 errors are not in a global variable e.g. 'errno' nor are
745 they congruent with posix error numbers. */
746
747static PyObject * os2_error(int code)
748{
749 char text[1024];
750 PyObject *v;
751
752 os2_strerror(text, sizeof(text), code, "");
753
754 v = Py_BuildValue("(is)", code, text);
755 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000756 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000757 Py_DECREF(v);
758 }
759 return NULL; /* Signal to Python that an Exception is Pending */
760}
761
762#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763
764/* POSIX generic methods */
765
Barry Warsaw53699e91996-12-10 23:23:01 +0000766static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000767posix_fildes(PyObject *fdobj, int (*func)(int))
768{
769 int fd;
770 int res;
771 fd = PyObject_AsFileDescriptor(fdobj);
772 if (fd < 0)
773 return NULL;
774 Py_BEGIN_ALLOW_THREADS
775 res = (*func)(fd);
776 Py_END_ALLOW_THREADS
777 if (res < 0)
778 return posix_error();
779 Py_INCREF(Py_None);
780 return Py_None;
781}
Guido van Rossum21142a01999-01-08 21:05:37 +0000782
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000783#ifdef Py_WIN_WIDE_FILENAMES
784static int
785unicode_file_names(void)
786{
787 static int canusewide = -1;
788 if (canusewide == -1) {
789 /* As per doc for ::GetVersion(), this is the correct test for
790 the Windows NT family. */
791 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
792 }
793 return canusewide;
794}
795#endif
796
Guido van Rossum21142a01999-01-08 21:05:37 +0000797static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000798posix_1str(PyObject *args, char *format, int (*func)(const char*),
799 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000800{
Mark Hammondef8b6542001-05-13 08:04:26 +0000801 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000802 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000803#ifdef Py_WIN_WIDE_FILENAMES
804 if (unicode_file_names()) {
805 PyUnicodeObject *po;
806 if (PyArg_ParseTuple(args, wformat, &po)) {
807 Py_BEGIN_ALLOW_THREADS
808 /* PyUnicode_AS_UNICODE OK without thread
809 lock as it is a simple dereference. */
810 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
811 Py_END_ALLOW_THREADS
812 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000813 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000814 Py_INCREF(Py_None);
815 return Py_None;
816 }
817 /* Drop the argument parsing error as narrow
818 strings are also valid. */
819 PyErr_Clear();
820 }
821#else
822 /* Platforms that don't support Unicode filenames
823 shouldn't be passing these extra params */
824 assert(wformat==NULL && wfunc == NULL);
825#endif
826
Tim Peters5aa91602002-01-30 05:46:57 +0000827 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000828 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000829 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000830 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000831 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000832 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000833 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000834 return posix_error_with_allocated_filename(path1);
835 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000836 Py_INCREF(Py_None);
837 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000838}
839
Barry Warsaw53699e91996-12-10 23:23:01 +0000840static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000841posix_2str(PyObject *args,
842 char *format,
843 int (*func)(const char *, const char *),
844 char *wformat,
845 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Mark Hammondef8b6542001-05-13 08:04:26 +0000847 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000848 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000849#ifdef Py_WIN_WIDE_FILENAMES
850 if (unicode_file_names()) {
851 PyObject *po1;
852 PyObject *po2;
853 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
854 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
855 PyObject *wpath1;
856 PyObject *wpath2;
857 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
858 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
859 if (!wpath1 || !wpath2) {
860 Py_XDECREF(wpath1);
861 Py_XDECREF(wpath2);
862 return NULL;
863 }
864 Py_BEGIN_ALLOW_THREADS
865 /* PyUnicode_AS_UNICODE OK without thread
866 lock as it is a simple dereference. */
867 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
868 PyUnicode_AS_UNICODE(wpath2));
869 Py_END_ALLOW_THREADS
870 Py_XDECREF(wpath1);
871 Py_XDECREF(wpath2);
872 if (res != 0)
873 return posix_error();
874 Py_INCREF(Py_None);
875 return Py_None;
876 }
877 /* Else flow through as neither is Unicode. */
878 }
879 /* Drop the argument parsing error as narrow
880 strings are also valid. */
881 PyErr_Clear();
882 }
883#else
884 /* Platforms that don't support Unicode filenames
885 shouldn't be passing these extra params */
886 assert(wformat==NULL && wfunc == NULL);
887#endif
888
Mark Hammondef8b6542001-05-13 08:04:26 +0000889 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000890 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000891 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000892 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000893 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000894 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000895 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000896 PyMem_Free(path1);
897 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000898 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000899 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000900 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000901 Py_INCREF(Py_None);
902 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000903}
904
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000905PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000906"stat_result: Result from stat or lstat.\n\n\
907This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000908 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000909or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
910\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000911Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000912they are available as attributes only.\n\
913\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000914See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000915
916static PyStructSequence_Field stat_result_fields[] = {
917 {"st_mode", "protection bits"},
918 {"st_ino", "inode"},
919 {"st_dev", "device"},
920 {"st_nlink", "number of hard links"},
921 {"st_uid", "user ID of owner"},
922 {"st_gid", "group ID of owner"},
923 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000924 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
925 {NULL, "integer time of last access"},
926 {NULL, "integer time of last modification"},
927 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000928 {"st_atime", "time of last access"},
929 {"st_mtime", "time of last modification"},
930 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000931#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000932 {"st_blksize", "blocksize for filesystem I/O"},
933#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000935 {"st_blocks", "number of blocks allocated"},
936#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938 {"st_rdev", "device type (if inode device)"},
939#endif
940 {0}
941};
942
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000943#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000944#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000945#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000946#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947#endif
948
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000949#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
951#else
952#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
953#endif
954
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000955#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000956#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
957#else
958#define ST_RDEV_IDX ST_BLOCKS_IDX
959#endif
960
961static PyStructSequence_Desc stat_result_desc = {
962 "stat_result", /* name */
963 stat_result__doc__, /* doc */
964 stat_result_fields,
965 10
966};
967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000968PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000969"statvfs_result: Result from statvfs or fstatvfs.\n\n\
970This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000971 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000972or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000973\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000974See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000975
976static PyStructSequence_Field statvfs_result_fields[] = {
977 {"f_bsize", },
978 {"f_frsize", },
979 {"f_blocks", },
980 {"f_bfree", },
981 {"f_bavail", },
982 {"f_files", },
983 {"f_ffree", },
984 {"f_favail", },
985 {"f_flag", },
986 {"f_namemax",},
987 {0}
988};
989
990static PyStructSequence_Desc statvfs_result_desc = {
991 "statvfs_result", /* name */
992 statvfs_result__doc__, /* doc */
993 statvfs_result_fields,
994 10
995};
996
997static PyTypeObject StatResultType;
998static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000999static newfunc structseq_new;
1000
1001static PyObject *
1002statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1003{
1004 PyStructSequence *result;
1005 int i;
1006
1007 result = (PyStructSequence*)structseq_new(type, args, kwds);
1008 if (!result)
1009 return NULL;
1010 /* If we have been initialized from a tuple,
1011 st_?time might be set to None. Initialize it
1012 from the int slots. */
1013 for (i = 7; i <= 9; i++) {
1014 if (result->ob_item[i+3] == Py_None) {
1015 Py_DECREF(Py_None);
1016 Py_INCREF(result->ob_item[i]);
1017 result->ob_item[i+3] = result->ob_item[i];
1018 }
1019 }
1020 return (PyObject*)result;
1021}
1022
1023
1024
1025/* If true, st_?time is float. */
1026static int _stat_float_times = 0;
1027
1028PyDoc_STRVAR(stat_float_times__doc__,
1029"stat_float_times([newval]) -> oldval\n\n\
1030Determine whether os.[lf]stat represents time stamps as float objects.\n\
1031If newval is True, future calls to stat() return floats, if it is False,\n\
1032future calls return ints. \n\
1033If newval is omitted, return the current setting.\n");
1034
1035static PyObject*
1036stat_float_times(PyObject* self, PyObject *args)
1037{
1038 int newval = -1;
1039 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1040 return NULL;
1041 if (newval == -1)
1042 /* Return old value */
1043 return PyBool_FromLong(_stat_float_times);
1044 _stat_float_times = newval;
1045 Py_INCREF(Py_None);
1046 return Py_None;
1047}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001048
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001049static void
1050fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1051{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001052 PyObject *fval,*ival;
1053#if SIZEOF_TIME_T > SIZEOF_LONG
1054 ival = PyLong_FromLongLong((LONG_LONG)sec);
1055#else
1056 ival = PyInt_FromLong((long)sec);
1057#endif
1058 if (_stat_float_times) {
1059 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1060 } else {
1061 fval = ival;
1062 Py_INCREF(fval);
1063 }
1064 PyStructSequence_SET_ITEM(v, index, ival);
1065 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001066}
1067
Tim Peters5aa91602002-01-30 05:46:57 +00001068/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001069 (used by posix_stat() and posix_fstat()) */
1070static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001071_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +00001072{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001073 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001074 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001075 if (v == NULL)
1076 return NULL;
1077
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001078 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001079#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001080 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001081 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001082#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001084#endif
1085#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001086 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001087 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001088#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001089 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001090#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001091 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
1092 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
1093 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001094#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001095 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001096 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001097#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001099#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001100
1101#ifdef HAVE_STAT_TV_NSEC
1102 ansec = st.st_atim.tv_nsec;
1103 mnsec = st.st_mtim.tv_nsec;
1104 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +00001105#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001106 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001108 fill_time(v, 7, st.st_atime, ansec);
1109 fill_time(v, 8, st.st_mtime, mnsec);
1110 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001111
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001112#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001113 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114 PyInt_FromLong((long)st.st_blksize));
1115#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001116#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001117 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001118 PyInt_FromLong((long)st.st_blocks));
1119#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001120#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001121 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1122 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001123#endif
1124
1125 if (PyErr_Occurred()) {
1126 Py_DECREF(v);
1127 return NULL;
1128 }
1129
1130 return v;
1131}
1132
Barry Warsaw53699e91996-12-10 23:23:01 +00001133static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001134posix_do_stat(PyObject *self, PyObject *args,
1135 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001136#ifdef __VMS
1137 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1138#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001139 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001140#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001141 char *wformat,
1142 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001143{
Fred Drake699f3522000-06-29 21:12:41 +00001144 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001145 char *path = NULL; /* pass this to stat; do not free() it */
1146 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001147 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001148
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001149#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +00001150 int pathlen;
1151 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001152#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001153
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001154
1155#ifdef Py_WIN_WIDE_FILENAMES
1156 /* If on wide-character-capable OS see if argument
1157 is Unicode and if so use wide API. */
1158 if (unicode_file_names()) {
1159 PyUnicodeObject *po;
1160 if (PyArg_ParseTuple(args, wformat, &po)) {
1161 Py_UNICODE wpath[MAX_PATH+1];
1162 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1163 /* the library call can blow up if the file name is too long! */
1164 if (pathlen > MAX_PATH) {
1165 errno = ENAMETOOLONG;
1166 return posix_error();
1167 }
1168 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1169 /* Remove trailing slash or backslash, unless it's the current
1170 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1171 */
1172 if (pathlen > 0 &&
1173 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1174 /* It does end with a slash -- exempt the root drive cases. */
1175 /* XXX UNC root drives should also be exempted? */
1176 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1177 /* leave it alone */;
1178 else {
1179 /* nuke the trailing backslash */
1180 wpath[pathlen-1] = L'\0';
1181 }
1182 }
1183 Py_BEGIN_ALLOW_THREADS
1184 /* PyUnicode_AS_UNICODE result OK without
1185 thread lock as it is a simple dereference. */
1186 res = wstatfunc(wpath, &st);
1187 Py_END_ALLOW_THREADS
1188 if (res != 0)
1189 return posix_error_with_unicode_filename(wpath);
1190 return _pystat_fromstructstat(st);
1191 }
1192 /* Drop the argument parsing error as narrow strings
1193 are also valid. */
1194 PyErr_Clear();
1195 }
1196#endif
1197
Tim Peters5aa91602002-01-30 05:46:57 +00001198 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001199 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001201 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001202
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001203#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001204 pathlen = strlen(path);
1205 /* the library call can blow up if the file name is too long! */
1206 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001207 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001208 errno = ENAMETOOLONG;
1209 return posix_error();
1210 }
1211
Tim Peters500bd032001-12-19 19:05:01 +00001212 /* Remove trailing slash or backslash, unless it's the current
1213 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1214 */
1215 if (pathlen > 0 &&
1216 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1217 /* It does end with a slash -- exempt the root drive cases. */
1218 /* XXX UNC root drives should also be exempted? */
1219 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1220 /* leave it alone */;
1221 else {
1222 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001223 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001224 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001225 path = pathcopy;
1226 }
1227 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001228#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001231 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001232 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001233 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001234 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001235
Tim Peters500bd032001-12-19 19:05:01 +00001236 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001237 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001238}
1239
1240
1241/* POSIX methods */
1242
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001243PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001244"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001245Use the real uid/gid to test for access to a path. Note that most\n\
1246operations will use the effective uid/gid, therefore this routine can\n\
1247be used in a suid/sgid environment to test if the invoking user has the\n\
1248specified access to the path. The mode argument can be F_OK to test\n\
1249existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001250
1251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001252posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001253{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001254 char *path;
1255 int mode;
1256 int res;
1257
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001258 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001259 return NULL;
1260 Py_BEGIN_ALLOW_THREADS
1261 res = access(path, mode);
1262 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001263 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001264}
1265
Guido van Rossumd371ff11999-01-25 16:12:23 +00001266#ifndef F_OK
1267#define F_OK 0
1268#endif
1269#ifndef R_OK
1270#define R_OK 4
1271#endif
1272#ifndef W_OK
1273#define W_OK 2
1274#endif
1275#ifndef X_OK
1276#define X_OK 1
1277#endif
1278
1279#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001280PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001281"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001282Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001283
1284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001285posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001286{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001287 int id;
1288 char *ret;
1289
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001290 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001291 return NULL;
1292
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001293#if defined(__VMS)
1294 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1295 if (id == 0) {
1296 ret = ttyname();
1297 }
1298 else {
1299 ret = NULL;
1300 }
1301#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001302 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001303#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001304 if (ret == NULL)
1305 return(posix_error());
1306 return(PyString_FromString(ret));
1307}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001308#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001309
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001310#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001311PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001312"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001313Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001314
1315static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001316posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001317{
1318 char *ret;
1319 char buffer[L_ctermid];
1320
Greg Wardb48bc172000-03-01 21:51:56 +00001321#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001322 ret = ctermid_r(buffer);
1323#else
1324 ret = ctermid(buffer);
1325#endif
1326 if (ret == NULL)
1327 return(posix_error());
1328 return(PyString_FromString(buffer));
1329}
1330#endif
1331
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001332PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001333"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001339#ifdef MS_WINDOWS
1340 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1341#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1342 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001343#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001344#ifdef __VMS
1345 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1346 NULL, NULL);
1347#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001348 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001349#endif
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001350#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351}
1352
Fred Drake4d1e64b2002-04-15 19:40:07 +00001353#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001354PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001355"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001356Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001358
1359static PyObject *
1360posix_fchdir(PyObject *self, PyObject *fdobj)
1361{
1362 return posix_fildes(fdobj, fchdir);
1363}
1364#endif /* HAVE_FCHDIR */
1365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001366
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001367PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001368"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001369Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001370
Barry Warsaw53699e91996-12-10 23:23:01 +00001371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001372posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001373{
Mark Hammondef8b6542001-05-13 08:04:26 +00001374 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001375 int i;
1376 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001377 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001378 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001379 return NULL;
1380 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001381 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001382 Py_END_ALLOW_THREADS
1383 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001384 return posix_error_with_allocated_filename(path);
1385 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001386 Py_INCREF(Py_None);
1387 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388}
1389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001390
Martin v. Löwis244edc82001-10-04 22:44:26 +00001391#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001392PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001393"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001394Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001395
1396static PyObject *
1397posix_chroot(PyObject *self, PyObject *args)
1398{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001399 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001400}
1401#endif
1402
Guido van Rossum21142a01999-01-08 21:05:37 +00001403#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001404PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001405"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001406force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001407
1408static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001409posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001410{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001411 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001412}
1413#endif /* HAVE_FSYNC */
1414
1415#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001416
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001417#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001418extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1419#endif
1420
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001421PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001422"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001423force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001424 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001425
1426static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001427posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001428{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001429 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001430}
1431#endif /* HAVE_FDATASYNC */
1432
1433
Fredrik Lundh10723342000-07-10 16:38:09 +00001434#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001436"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001437Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001438
Barry Warsaw53699e91996-12-10 23:23:01 +00001439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001440posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001441{
Mark Hammondef8b6542001-05-13 08:04:26 +00001442 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001443 int uid, gid;
1444 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001445 if (!PyArg_ParseTuple(args, "etii:chown",
1446 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001447 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001448 return NULL;
1449 Py_BEGIN_ALLOW_THREADS
1450 res = chown(path, (uid_t) uid, (gid_t) gid);
1451 Py_END_ALLOW_THREADS
1452 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001453 return posix_error_with_allocated_filename(path);
1454 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001455 Py_INCREF(Py_None);
1456 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001457}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001458#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001459
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001460#ifdef HAVE_LCHOWN
1461PyDoc_STRVAR(posix_lchown__doc__,
1462"lchown(path, uid, gid)\n\n\
1463Change the owner and group id of path to the numeric uid and gid.\n\
1464This function will not follow symbolic links.");
1465
1466static PyObject *
1467posix_lchown(PyObject *self, PyObject *args)
1468{
1469 char *path = NULL;
1470 int uid, gid;
1471 int res;
1472 if (!PyArg_ParseTuple(args, "etii:lchown",
1473 Py_FileSystemDefaultEncoding, &path,
1474 &uid, &gid))
1475 return NULL;
1476 Py_BEGIN_ALLOW_THREADS
1477 res = lchown(path, (uid_t) uid, (gid_t) gid);
1478 Py_END_ALLOW_THREADS
Neal Norwitze241ce82003-02-17 18:17:05 +00001479 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001480 return posix_error_with_allocated_filename(path);
1481 PyMem_Free(path);
1482 Py_INCREF(Py_None);
1483 return Py_None;
1484}
1485#endif /* HAVE_LCHOWN */
1486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001487
Guido van Rossum36bc6801995-06-14 22:54:23 +00001488#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001490"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001491Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001492
Barry Warsaw53699e91996-12-10 23:23:01 +00001493static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001494posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001495{
1496 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001497 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001498
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 *
Neal Norwitze241ce82003-02-17 18:17:05 +00001522posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001523{
1524 char buf[1026];
1525 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001526
1527#ifdef Py_WIN_WIDE_FILENAMES
1528 if (unicode_file_names()) {
1529 wchar_t *wres;
1530 wchar_t wbuf[1026];
1531 Py_BEGIN_ALLOW_THREADS
1532 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1533 Py_END_ALLOW_THREADS
1534 if (wres == NULL)
1535 return posix_error();
1536 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1537 }
1538#endif
1539
1540 Py_BEGIN_ALLOW_THREADS
1541#if defined(PYOS_OS2) && defined(PYCC_GCC)
1542 res = _getcwd2(buf, sizeof buf);
1543#else
1544 res = getcwd(buf, sizeof buf);
1545#endif
1546 Py_END_ALLOW_THREADS
1547 if (res == NULL)
1548 return posix_error();
1549 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1550}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001551#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001552#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001554
Guido van Rossumb6775db1994-08-01 11:34:53 +00001555#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001556PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001557"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001558Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001559
Barry Warsaw53699e91996-12-10 23:23:01 +00001560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001561posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001562{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001563 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001564}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001565#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001566
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001568PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001569"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001570Return a list containing the names of the entries in the directory.\n\
1571\n\
1572 path: path of directory to list\n\
1573\n\
1574The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001575entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001576
Barry Warsaw53699e91996-12-10 23:23:01 +00001577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001578posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001579{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001580 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001581 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001582#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001583
Barry Warsaw53699e91996-12-10 23:23:01 +00001584 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001585 HANDLE hFindFile;
1586 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001587 /* MAX_PATH characters could mean a bigger encoded string */
1588 char namebuf[MAX_PATH*2+5];
1589 char *bufptr = namebuf;
1590 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001591
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001592#ifdef Py_WIN_WIDE_FILENAMES
1593 /* If on wide-character-capable OS see if argument
1594 is Unicode and if so use wide API. */
1595 if (unicode_file_names()) {
1596 PyUnicodeObject *po;
1597 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1598 WIN32_FIND_DATAW wFileData;
1599 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1600 Py_UNICODE wch;
1601 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1602 wnamebuf[MAX_PATH] = L'\0';
1603 len = wcslen(wnamebuf);
1604 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1605 if (wch != L'/' && wch != L'\\' && wch != L':')
1606 wnamebuf[len++] = L'/';
1607 wcscpy(wnamebuf + len, L"*.*");
1608 if ((d = PyList_New(0)) == NULL)
1609 return NULL;
1610 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1611 if (hFindFile == INVALID_HANDLE_VALUE) {
1612 errno = GetLastError();
1613 if (errno == ERROR_FILE_NOT_FOUND) {
1614 return d;
1615 }
1616 Py_DECREF(d);
1617 return win32_error_unicode("FindFirstFileW", wnamebuf);
1618 }
1619 do {
1620 if (wFileData.cFileName[0] == L'.' &&
1621 (wFileData.cFileName[1] == L'\0' ||
1622 wFileData.cFileName[1] == L'.' &&
1623 wFileData.cFileName[2] == L'\0'))
1624 continue;
1625 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1626 if (v == NULL) {
1627 Py_DECREF(d);
1628 d = NULL;
1629 break;
1630 }
1631 if (PyList_Append(d, v) != 0) {
1632 Py_DECREF(v);
1633 Py_DECREF(d);
1634 d = NULL;
1635 break;
1636 }
1637 Py_DECREF(v);
1638 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1639
1640 if (FindClose(hFindFile) == FALSE) {
1641 Py_DECREF(d);
1642 return win32_error_unicode("FindClose", wnamebuf);
1643 }
1644 return d;
1645 }
1646 /* Drop the argument parsing error as narrow strings
1647 are also valid. */
1648 PyErr_Clear();
1649 }
1650#endif
1651
Tim Peters5aa91602002-01-30 05:46:57 +00001652 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001653 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001654 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001655 if (len > 0) {
1656 char ch = namebuf[len-1];
1657 if (ch != SEP && ch != ALTSEP && ch != ':')
1658 namebuf[len++] = '/';
1659 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001660 strcpy(namebuf + len, "*.*");
1661
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663 return NULL;
1664
1665 hFindFile = FindFirstFile(namebuf, &FileData);
1666 if (hFindFile == INVALID_HANDLE_VALUE) {
1667 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001668 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001669 return d;
1670 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001671 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001672 }
1673 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001674 if (FileData.cFileName[0] == '.' &&
1675 (FileData.cFileName[1] == '\0' ||
1676 FileData.cFileName[1] == '.' &&
1677 FileData.cFileName[2] == '\0'))
1678 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001679 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001680 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001681 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001682 d = NULL;
1683 break;
1684 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001685 if (PyList_Append(d, v) != 0) {
1686 Py_DECREF(v);
1687 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001688 d = NULL;
1689 break;
1690 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001691 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001692 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1693
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001694 if (FindClose(hFindFile) == FALSE) {
1695 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001696 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001697 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001698
1699 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001700
Tim Peters0bb44a42000-09-15 07:44:49 +00001701#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001702
1703#ifndef MAX_PATH
1704#define MAX_PATH CCHMAXPATH
1705#endif
1706 char *name, *pt;
1707 int len;
1708 PyObject *d, *v;
1709 char namebuf[MAX_PATH+5];
1710 HDIR hdir = 1;
1711 ULONG srchcnt = 1;
1712 FILEFINDBUF3 ep;
1713 APIRET rc;
1714
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001715 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001716 return NULL;
1717 if (len >= MAX_PATH) {
1718 PyErr_SetString(PyExc_ValueError, "path too long");
1719 return NULL;
1720 }
1721 strcpy(namebuf, name);
1722 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001723 if (*pt == ALTSEP)
1724 *pt = SEP;
1725 if (namebuf[len-1] != SEP)
1726 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001727 strcpy(namebuf + len, "*.*");
1728
1729 if ((d = PyList_New(0)) == NULL)
1730 return NULL;
1731
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001732 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1733 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001734 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001735 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1736 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1737 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001738
1739 if (rc != NO_ERROR) {
1740 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001741 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001742 }
1743
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001744 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001745 do {
1746 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001747 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001748 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001749
1750 strcpy(namebuf, ep.achName);
1751
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001752 /* Leave Case of Name Alone -- In Native Form */
1753 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001754
1755 v = PyString_FromString(namebuf);
1756 if (v == NULL) {
1757 Py_DECREF(d);
1758 d = NULL;
1759 break;
1760 }
1761 if (PyList_Append(d, v) != 0) {
1762 Py_DECREF(v);
1763 Py_DECREF(d);
1764 d = NULL;
1765 break;
1766 }
1767 Py_DECREF(v);
1768 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1769 }
1770
1771 return d;
1772#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001773
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001774 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001775 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001776 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001777 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001778 int arg_is_unicode = 1;
1779
1780 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1781 arg_is_unicode = 0;
1782 PyErr_Clear();
1783 }
1784 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001785 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001786 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001787 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001788 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001789 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001790 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001791 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001792 return NULL;
1793 }
1794 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001795 if (ep->d_name[0] == '.' &&
1796 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001797 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001798 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001800 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001801 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001802 d = NULL;
1803 break;
1804 }
Just van Rossum46c97842003-02-25 21:42:15 +00001805#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001806 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001807 PyObject *w;
1808
1809 w = PyUnicode_FromEncodedObject(v,
1810 Py_FileSystemDefaultEncoding,
1811 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001812 if (w != NULL) {
1813 Py_DECREF(v);
1814 v = w;
1815 }
1816 else {
1817 /* fall back to the original byte string, as
1818 discussed in patch #683592 */
1819 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001820 }
Just van Rossum46c97842003-02-25 21:42:15 +00001821 }
1822#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001823 if (PyList_Append(d, v) != 0) {
1824 Py_DECREF(v);
1825 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001826 d = NULL;
1827 break;
1828 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001829 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830 }
1831 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001832 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001833
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001834 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001835
Tim Peters0bb44a42000-09-15 07:44:49 +00001836#endif /* which OS */
1837} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001838
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001839#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001840/* A helper function for abspath on win32 */
1841static PyObject *
1842posix__getfullpathname(PyObject *self, PyObject *args)
1843{
1844 /* assume encoded strings wont more than double no of chars */
1845 char inbuf[MAX_PATH*2];
1846 char *inbufp = inbuf;
1847 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1848 char outbuf[MAX_PATH*2];
1849 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001850#ifdef Py_WIN_WIDE_FILENAMES
1851 if (unicode_file_names()) {
1852 PyUnicodeObject *po;
1853 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1854 Py_UNICODE woutbuf[MAX_PATH*2];
1855 Py_UNICODE *wtemp;
1856 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1857 sizeof(woutbuf)/sizeof(woutbuf[0]),
1858 woutbuf, &wtemp))
1859 return win32_error("GetFullPathName", "");
1860 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1861 }
1862 /* Drop the argument parsing error as narrow strings
1863 are also valid. */
1864 PyErr_Clear();
1865 }
1866#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001867 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1868 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001869 &insize))
1870 return NULL;
1871 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1872 outbuf, &temp))
1873 return win32_error("GetFullPathName", inbuf);
1874 return PyString_FromString(outbuf);
1875} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001876#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001879"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001880Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001884{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001885 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001886 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001887 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001888
1889#ifdef Py_WIN_WIDE_FILENAMES
1890 if (unicode_file_names()) {
1891 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001892 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001893 Py_BEGIN_ALLOW_THREADS
1894 /* PyUnicode_AS_UNICODE OK without thread lock as
1895 it is a simple dereference. */
1896 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1897 Py_END_ALLOW_THREADS
1898 if (res < 0)
1899 return posix_error();
1900 Py_INCREF(Py_None);
1901 return Py_None;
1902 }
1903 /* Drop the argument parsing error as narrow strings
1904 are also valid. */
1905 PyErr_Clear();
1906 }
1907#endif
1908
Tim Peters5aa91602002-01-30 05:46:57 +00001909 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001910 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001911 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001912 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001913#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001914 res = mkdir(path);
1915#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001916 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001917#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001918 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001919 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001920 return posix_error_with_allocated_filename(path);
1921 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001922 Py_INCREF(Py_None);
1923 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001924}
1925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001926
Guido van Rossumb6775db1994-08-01 11:34:53 +00001927#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001928#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1929#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1930#include <sys/resource.h>
1931#endif
1932#endif
1933
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001934PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001935"nice(inc) -> new_priority\n\n\
1936Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001937
Barry Warsaw53699e91996-12-10 23:23:01 +00001938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001939posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001940{
1941 int increment, value;
1942
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001943 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001944 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001945
1946 /* There are two flavours of 'nice': one that returns the new
1947 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001948 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1949 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001950
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001951 If we are of the nice family that returns the new priority, we
1952 need to clear errno before the call, and check if errno is filled
1953 before calling posix_error() on a returnvalue of -1, because the
1954 -1 may be the actual new priority! */
1955
1956 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001957 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001958#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001959 if (value == 0)
1960 value = getpriority(PRIO_PROCESS, 0);
1961#endif
1962 if (value == -1 && errno != 0)
1963 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001964 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001965 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001966}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001967#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001972Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001973
Barry Warsaw53699e91996-12-10 23:23:01 +00001974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001975posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001976{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001977#ifdef MS_WINDOWS
1978 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1979#else
1980 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1981#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001982}
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001985PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001986"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001987Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001988
Barry Warsaw53699e91996-12-10 23:23:01 +00001989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001990posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001991{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001992#ifdef MS_WINDOWS
1993 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1994#else
1995 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1996#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001997}
1998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002000PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002001"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002002Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003
Barry Warsaw53699e91996-12-10 23:23:01 +00002004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002005posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002006{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002007#ifdef MS_WINDOWS
2008 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
2009#else
2010 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2011#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002012}
2013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002015#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002017"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002018Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002019
Barry Warsaw53699e91996-12-10 23:23:01 +00002020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002022{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002023 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002024 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002025 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002026 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002028 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002029 Py_END_ALLOW_THREADS
2030 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002031}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002032#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002036"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002038
Barry Warsaw53699e91996-12-10 23:23:01 +00002039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002040posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002041{
2042 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002043 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002045 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002046 if (i < 0)
2047 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002048 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002049}
2050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002051
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002053"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002056PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002057"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Barry Warsaw53699e91996-12-10 23:23:01 +00002060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002061posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002063#ifdef MS_WINDOWS
2064 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2065#else
2066 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2067#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068}
2069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002072PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002073"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Barry Warsaw53699e91996-12-10 23:23:01 +00002076static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002077posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002078{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002079 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002080 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002081
Barry Warsaw53699e91996-12-10 23:23:01 +00002082 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002083 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002084 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002085 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002086 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002087 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002088 u.sysname,
2089 u.nodename,
2090 u.release,
2091 u.version,
2092 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002093}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002095
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002096static int
2097extract_time(PyObject *t, long* sec, long* usec)
2098{
2099 long intval;
2100 if (PyFloat_Check(t)) {
2101 double tval = PyFloat_AsDouble(t);
2102 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2103 if (!intobj)
2104 return -1;
2105 intval = PyInt_AsLong(intobj);
2106 Py_DECREF(intobj);
2107 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002108 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002109 if (*usec < 0)
2110 /* If rounding gave us a negative number,
2111 truncate. */
2112 *usec = 0;
2113 return 0;
2114 }
2115 intval = PyInt_AsLong(t);
2116 if (intval == -1 && PyErr_Occurred())
2117 return -1;
2118 *sec = intval;
2119 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002120 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002121}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002123PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002124"utime(path, (atime, utime))\n\
2125utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002126Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002127second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002128
Barry Warsaw53699e91996-12-10 23:23:01 +00002129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002130posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002131{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002132 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002133 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002134 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002135 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002136
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002137#if defined(HAVE_UTIMES)
2138 struct timeval buf[2];
2139#define ATIME buf[0].tv_sec
2140#define MTIME buf[1].tv_sec
2141#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002142/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002143 struct utimbuf buf;
2144#define ATIME buf.actime
2145#define MTIME buf.modtime
2146#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002147#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002148 time_t buf[2];
2149#define ATIME buf[0]
2150#define MTIME buf[1]
2151#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002152#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002153
Barry Warsaw3cef8562000-05-01 16:17:24 +00002154 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002155 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002156 if (arg == Py_None) {
2157 /* optional time values not given */
2158 Py_BEGIN_ALLOW_THREADS
2159 res = utime(path, NULL);
2160 Py_END_ALLOW_THREADS
2161 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002162 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002163 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002164 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002165 return NULL;
2166 }
2167 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002168 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2169 &atime, &ausec) == -1)
2170 return NULL;
2171 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2172 &mtime, &musec) == -1)
2173 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002174 ATIME = atime;
2175 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002176#ifdef HAVE_UTIMES
2177 buf[0].tv_usec = ausec;
2178 buf[1].tv_usec = musec;
2179 Py_BEGIN_ALLOW_THREADS
2180 res = utimes(path, buf);
2181 Py_END_ALLOW_THREADS
2182#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002183 Py_BEGIN_ALLOW_THREADS
2184 res = utime(path, UTIME_ARG);
2185 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002186#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002187 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002188 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002189 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002190 Py_INCREF(Py_None);
2191 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002192#undef UTIME_ARG
2193#undef ATIME
2194#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002195}
2196
Guido van Rossum85e3b011991-06-03 12:42:10 +00002197
Guido van Rossum3b066191991-06-04 19:40:25 +00002198/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002200PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002201"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002202Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002203
Barry Warsaw53699e91996-12-10 23:23:01 +00002204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002205posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002206{
2207 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002208 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002209 return NULL;
2210 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002211 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002212}
2213
Martin v. Löwis114619e2002-10-07 06:44:21 +00002214#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2215static void
2216free_string_array(char **array, int count)
2217{
2218 int i;
2219 for (i = 0; i < count; i++)
2220 PyMem_Free(array[i]);
2221 PyMem_DEL(array);
2222}
2223#endif
2224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002226#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002227PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002228"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229Execute an executable path with arguments, replacing current process.\n\
2230\n\
2231 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002232 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002233
Barry Warsaw53699e91996-12-10 23:23:01 +00002234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002235posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002236{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002237 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002238 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002239 char **argvlist;
2240 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002241 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002242
Guido van Rossum89b33251993-10-22 14:26:06 +00002243 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002244 argv is a list or tuple of strings. */
2245
Martin v. Löwis114619e2002-10-07 06:44:21 +00002246 if (!PyArg_ParseTuple(args, "etO:execv",
2247 Py_FileSystemDefaultEncoding,
2248 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002249 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002250 if (PyList_Check(argv)) {
2251 argc = PyList_Size(argv);
2252 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002253 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002254 else if (PyTuple_Check(argv)) {
2255 argc = PyTuple_Size(argv);
2256 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002257 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002258 else {
Fred Drake661ea262000-10-24 19:57:45 +00002259 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002260 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002261 return NULL;
2262 }
2263
2264 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002265 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002266 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002267 return NULL;
2268 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002269
Barry Warsaw53699e91996-12-10 23:23:01 +00002270 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002271 if (argvlist == NULL) {
2272 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002273 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002274 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002275 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002276 if (!PyArg_Parse((*getitem)(argv, i), "et",
2277 Py_FileSystemDefaultEncoding,
2278 &argvlist[i])) {
2279 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002280 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002281 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002282 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002283 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002284
Guido van Rossum85e3b011991-06-03 12:42:10 +00002285 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002286 }
2287 argvlist[argc] = NULL;
2288
Guido van Rossumb6775db1994-08-01 11:34:53 +00002289#ifdef BAD_EXEC_PROTOTYPES
2290 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002291#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002292 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002293#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002294
Guido van Rossum85e3b011991-06-03 12:42:10 +00002295 /* If we get here it's definitely an error */
2296
Martin v. Löwis114619e2002-10-07 06:44:21 +00002297 free_string_array(argvlist, argc);
2298 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002299 return posix_error();
2300}
2301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002303PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002304"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002305Execute a path with arguments and environment, replacing current process.\n\
2306\n\
2307 path: path of executable file\n\
2308 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002309 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002310
Barry Warsaw53699e91996-12-10 23:23:01 +00002311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002312posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002313{
2314 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002315 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002316 char **argvlist;
2317 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002318 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002319 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002320 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002321 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002322
2323 /* execve has three arguments: (path, argv, env), where
2324 argv is a list or tuple of strings and env is a dictionary
2325 like posix.environ. */
2326
Martin v. Löwis114619e2002-10-07 06:44:21 +00002327 if (!PyArg_ParseTuple(args, "etOO:execve",
2328 Py_FileSystemDefaultEncoding,
2329 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002330 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002331 if (PyList_Check(argv)) {
2332 argc = PyList_Size(argv);
2333 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 else if (PyTuple_Check(argv)) {
2336 argc = PyTuple_Size(argv);
2337 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002338 }
2339 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002340 PyErr_SetString(PyExc_TypeError,
2341 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002342 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002343 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002344 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002345 PyErr_SetString(PyExc_TypeError,
2346 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002347 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002348 }
2349
Guido van Rossum50422b42000-04-26 20:34:28 +00002350 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002351 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002352 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002353 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002354 }
2355
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002357 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002358 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002359 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002360 }
2361 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002363 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002364 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002365 &argvlist[i]))
2366 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002368 goto fail_1;
2369 }
2370 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002371 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002372 argvlist[argc] = NULL;
2373
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002374 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002375 if (i < 0)
2376 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002377 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002378 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002379 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002380 goto fail_1;
2381 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002382 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002383 keys = PyMapping_Keys(env);
2384 vals = PyMapping_Values(env);
2385 if (!keys || !vals)
2386 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002387 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2388 PyErr_SetString(PyExc_TypeError,
2389 "execve(): env.keys() or env.values() is not a list");
2390 goto fail_2;
2391 }
Tim Peters5aa91602002-01-30 05:46:57 +00002392
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002393 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002394 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002395 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002396
2397 key = PyList_GetItem(keys, pos);
2398 val = PyList_GetItem(vals, pos);
2399 if (!key || !val)
2400 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002401
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002402 if (!PyArg_Parse(
2403 key,
2404 "s;execve() arg 3 contains a non-string key",
2405 &k) ||
2406 !PyArg_Parse(
2407 val,
2408 "s;execve() arg 3 contains a non-string value",
2409 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002410 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002411 goto fail_2;
2412 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002413
2414#if defined(PYOS_OS2)
2415 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2416 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2417#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002418 len = PyString_Size(key) + PyString_Size(val) + 2;
2419 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002420 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002421 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002422 goto fail_2;
2423 }
Tim Petersc8996f52001-12-03 20:41:00 +00002424 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002425 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002426#if defined(PYOS_OS2)
2427 }
2428#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002429 }
2430 envlist[envc] = 0;
2431
Guido van Rossumb6775db1994-08-01 11:34:53 +00002432
2433#ifdef BAD_EXEC_PROTOTYPES
2434 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002435#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002436 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002437#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002438
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002439 /* If we get here it's definitely an error */
2440
2441 (void) posix_error();
2442
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002443 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002444 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002445 PyMem_DEL(envlist[envc]);
2446 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002447 fail_1:
2448 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002449 Py_XDECREF(vals);
2450 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002451 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002452 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002453 return NULL;
2454}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002455#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002457
Guido van Rossuma1065681999-01-25 23:20:23 +00002458#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002459PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002460"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002461Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002462\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002463 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002464 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002465 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002466
2467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002468posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002469{
2470 char *path;
2471 PyObject *argv;
2472 char **argvlist;
2473 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002474 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002475 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002476
2477 /* spawnv has three arguments: (mode, path, argv), where
2478 argv is a list or tuple of strings. */
2479
Martin v. Löwis114619e2002-10-07 06:44:21 +00002480 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2481 Py_FileSystemDefaultEncoding,
2482 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002483 return NULL;
2484 if (PyList_Check(argv)) {
2485 argc = PyList_Size(argv);
2486 getitem = PyList_GetItem;
2487 }
2488 else if (PyTuple_Check(argv)) {
2489 argc = PyTuple_Size(argv);
2490 getitem = PyTuple_GetItem;
2491 }
2492 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002493 PyErr_SetString(PyExc_TypeError,
2494 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002495 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002496 return NULL;
2497 }
2498
2499 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002500 if (argvlist == NULL) {
2501 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002502 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002503 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002504 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002505 if (!PyArg_Parse((*getitem)(argv, i), "et",
2506 Py_FileSystemDefaultEncoding,
2507 &argvlist[i])) {
2508 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002509 PyErr_SetString(
2510 PyExc_TypeError,
2511 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002512 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002513 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002514 }
2515 }
2516 argvlist[argc] = NULL;
2517
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002518#if defined(PYOS_OS2) && defined(PYCC_GCC)
2519 Py_BEGIN_ALLOW_THREADS
2520 spawnval = spawnv(mode, path, argvlist);
2521 Py_END_ALLOW_THREADS
2522#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002523 if (mode == _OLD_P_OVERLAY)
2524 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002525
Tim Peters25059d32001-12-07 20:35:43 +00002526 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002527 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002528 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002529#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002530
Martin v. Löwis114619e2002-10-07 06:44:21 +00002531 free_string_array(argvlist, argc);
2532 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002533
Fred Drake699f3522000-06-29 21:12:41 +00002534 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002535 return posix_error();
2536 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002537#if SIZEOF_LONG == SIZEOF_VOID_P
2538 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002539#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002540 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002541#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002542}
2543
2544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002546"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002547Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002548\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002549 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002550 path: path of executable file\n\
2551 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002553
2554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002555posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002556{
2557 char *path;
2558 PyObject *argv, *env;
2559 char **argvlist;
2560 char **envlist;
2561 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2562 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002563 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002564 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002565 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002566
2567 /* spawnve has four arguments: (mode, path, argv, env), where
2568 argv is a list or tuple of strings and env is a dictionary
2569 like posix.environ. */
2570
Martin v. Löwis114619e2002-10-07 06:44:21 +00002571 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2572 Py_FileSystemDefaultEncoding,
2573 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002574 return NULL;
2575 if (PyList_Check(argv)) {
2576 argc = PyList_Size(argv);
2577 getitem = PyList_GetItem;
2578 }
2579 else if (PyTuple_Check(argv)) {
2580 argc = PyTuple_Size(argv);
2581 getitem = PyTuple_GetItem;
2582 }
2583 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002584 PyErr_SetString(PyExc_TypeError,
2585 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002587 }
2588 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002589 PyErr_SetString(PyExc_TypeError,
2590 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002591 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002592 }
2593
2594 argvlist = PyMem_NEW(char *, argc+1);
2595 if (argvlist == NULL) {
2596 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002597 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002598 }
2599 for (i = 0; i < argc; i++) {
2600 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002601 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002602 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002603 &argvlist[i]))
2604 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002605 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002606 goto fail_1;
2607 }
2608 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002609 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002610 argvlist[argc] = NULL;
2611
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002612 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002613 if (i < 0)
2614 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002615 envlist = PyMem_NEW(char *, i + 1);
2616 if (envlist == NULL) {
2617 PyErr_NoMemory();
2618 goto fail_1;
2619 }
2620 envc = 0;
2621 keys = PyMapping_Keys(env);
2622 vals = PyMapping_Values(env);
2623 if (!keys || !vals)
2624 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002625 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2626 PyErr_SetString(PyExc_TypeError,
2627 "spawnve(): env.keys() or env.values() is not a list");
2628 goto fail_2;
2629 }
Tim Peters5aa91602002-01-30 05:46:57 +00002630
Guido van Rossuma1065681999-01-25 23:20:23 +00002631 for (pos = 0; pos < i; pos++) {
2632 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002633 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002634
2635 key = PyList_GetItem(keys, pos);
2636 val = PyList_GetItem(vals, pos);
2637 if (!key || !val)
2638 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002639
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002640 if (!PyArg_Parse(
2641 key,
2642 "s;spawnve() arg 3 contains a non-string key",
2643 &k) ||
2644 !PyArg_Parse(
2645 val,
2646 "s;spawnve() arg 3 contains a non-string value",
2647 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002648 {
2649 goto fail_2;
2650 }
Tim Petersc8996f52001-12-03 20:41:00 +00002651 len = PyString_Size(key) + PyString_Size(val) + 2;
2652 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002653 if (p == NULL) {
2654 PyErr_NoMemory();
2655 goto fail_2;
2656 }
Tim Petersc8996f52001-12-03 20:41:00 +00002657 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002658 envlist[envc++] = p;
2659 }
2660 envlist[envc] = 0;
2661
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002662#if defined(PYOS_OS2) && defined(PYCC_GCC)
2663 Py_BEGIN_ALLOW_THREADS
2664 spawnval = spawnve(mode, path, argvlist, envlist);
2665 Py_END_ALLOW_THREADS
2666#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002667 if (mode == _OLD_P_OVERLAY)
2668 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002669
2670 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002671 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002672 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002673#endif
Tim Peters25059d32001-12-07 20:35:43 +00002674
Fred Drake699f3522000-06-29 21:12:41 +00002675 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002676 (void) posix_error();
2677 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002678#if SIZEOF_LONG == SIZEOF_VOID_P
2679 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002680#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002681 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002682#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002683
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002684 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002685 while (--envc >= 0)
2686 PyMem_DEL(envlist[envc]);
2687 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002688 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002689 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002690 Py_XDECREF(vals);
2691 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002692 fail_0:
2693 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002694 return res;
2695}
2696#endif /* HAVE_SPAWNV */
2697
2698
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002699#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002701"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002702Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2703\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002705
2706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002707posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002708{
Neal Norwitze241ce82003-02-17 18:17:05 +00002709 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002710 if (pid == -1)
2711 return posix_error();
2712 PyOS_AfterFork();
2713 return PyInt_FromLong((long)pid);
2714}
2715#endif
2716
2717
Guido van Rossumad0ee831995-03-01 10:34:45 +00002718#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002719PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002720"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002722Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002723
Barry Warsaw53699e91996-12-10 23:23:01 +00002724static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002725posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002726{
Neal Norwitze241ce82003-02-17 18:17:05 +00002727 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002728 if (pid == -1)
2729 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002730 if (pid == 0)
2731 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002732 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002733}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002734#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002735
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002736#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002737#ifdef HAVE_PTY_H
2738#include <pty.h>
2739#else
2740#ifdef HAVE_LIBUTIL_H
2741#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002742#endif /* HAVE_LIBUTIL_H */
2743#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002744#ifdef HAVE_STROPTS_H
2745#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002746#endif
2747#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002748
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002749#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002750PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002751"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002752Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002753
2754static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002755posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002756{
2757 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002758#ifndef HAVE_OPENPTY
2759 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002760#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002761#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002762 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002763#ifdef sun
2764 extern char *ptsname();
2765#endif
2766#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002767
Thomas Wouters70c21a12000-07-14 14:28:33 +00002768#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002769 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2770 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002771#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002772 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2773 if (slave_name == NULL)
2774 return posix_error();
2775
2776 slave_fd = open(slave_name, O_RDWR);
2777 if (slave_fd < 0)
2778 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002779#else
2780 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2781 if (master_fd < 0)
2782 return posix_error();
2783 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002784 /* change permission of slave */
2785 if (grantpt(master_fd) < 0) {
2786 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002787 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002788 }
2789 /* unlock slave */
2790 if (unlockpt(master_fd) < 0) {
2791 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002792 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002793 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002794 signal(SIGCHLD, sig_saved);
2795 slave_name = ptsname(master_fd); /* get name of slave */
2796 if (slave_name == NULL)
2797 return posix_error();
2798 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2799 if (slave_fd < 0)
2800 return posix_error();
2801#ifndef __CYGWIN__
2802 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2803 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002804#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002805 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002806#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002807#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002808#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002809
Fred Drake8cef4cf2000-06-28 16:40:38 +00002810 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002811
Fred Drake8cef4cf2000-06-28 16:40:38 +00002812}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002813#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002814
2815#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002816PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002817"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002818Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2819Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002821
2822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002823posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002824{
2825 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002826
Fred Drake8cef4cf2000-06-28 16:40:38 +00002827 pid = forkpty(&master_fd, NULL, NULL, NULL);
2828 if (pid == -1)
2829 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002830 if (pid == 0)
2831 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002832 return Py_BuildValue("(ii)", pid, master_fd);
2833}
2834#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Guido van Rossumad0ee831995-03-01 10:34:45 +00002836#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002838"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002840
Barry Warsaw53699e91996-12-10 23:23:01 +00002841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002842posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002843{
Barry Warsaw53699e91996-12-10 23:23:01 +00002844 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002845}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002846#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002848
Guido van Rossumad0ee831995-03-01 10:34:45 +00002849#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002850PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002851"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002852Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002853
Barry Warsaw53699e91996-12-10 23:23:01 +00002854static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002855posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002856{
Barry Warsaw53699e91996-12-10 23:23:01 +00002857 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002858}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002859#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002861
Guido van Rossumad0ee831995-03-01 10:34:45 +00002862#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002864"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002865Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002866
Barry Warsaw53699e91996-12-10 23:23:01 +00002867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002868posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002869{
Barry Warsaw53699e91996-12-10 23:23:01 +00002870 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002871}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002872#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002880posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002881{
Barry Warsaw53699e91996-12-10 23:23:01 +00002882 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002883}
2884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002885
Fred Drakec9680921999-12-13 16:37:25 +00002886#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002887PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002888"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002890
2891static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002892posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002893{
2894 PyObject *result = NULL;
2895
Fred Drakec9680921999-12-13 16:37:25 +00002896#ifdef NGROUPS_MAX
2897#define MAX_GROUPS NGROUPS_MAX
2898#else
2899 /* defined to be 16 on Solaris7, so this should be a small number */
2900#define MAX_GROUPS 64
2901#endif
2902 gid_t grouplist[MAX_GROUPS];
2903 int n;
2904
2905 n = getgroups(MAX_GROUPS, grouplist);
2906 if (n < 0)
2907 posix_error();
2908 else {
2909 result = PyList_New(n);
2910 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002911 int i;
2912 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002913 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002914 if (o == NULL) {
2915 Py_DECREF(result);
2916 result = NULL;
2917 break;
2918 }
2919 PyList_SET_ITEM(result, i, o);
2920 }
2921 }
2922 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002923
Fred Drakec9680921999-12-13 16:37:25 +00002924 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 *
Neal Norwitze241ce82003-02-17 18:17:05 +00002953posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002954{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002955#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002956 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002957#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002958 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002959#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002960}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002961#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002963
Guido van Rossumb6775db1994-08-01 11:34:53 +00002964#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002966"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002967Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002968
Barry Warsaw53699e91996-12-10 23:23:01 +00002969static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002970posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002971{
Guido van Rossum64933891994-10-20 21:56:42 +00002972#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002973 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002974#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002975 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002976#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002977 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002978 Py_INCREF(Py_None);
2979 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002980}
2981
Guido van Rossumb6775db1994-08-01 11:34:53 +00002982#endif /* HAVE_SETPGRP */
2983
Guido van Rossumad0ee831995-03-01 10:34:45 +00002984#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002985PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002986"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002987Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002988
Barry Warsaw53699e91996-12-10 23:23:01 +00002989static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002990posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002991{
Barry Warsaw53699e91996-12-10 23:23:01 +00002992 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002993}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002994#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996
Fred Drake12c6e2d1999-12-14 21:25:03 +00002997#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002998PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002999"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003000Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003001
3002static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003003posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003004{
Neal Norwitze241ce82003-02-17 18:17:05 +00003005 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003006 char *name;
3007 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003008
Fred Drakea30680b2000-12-06 21:24:28 +00003009 errno = 0;
3010 name = getlogin();
3011 if (name == NULL) {
3012 if (errno)
3013 posix_error();
3014 else
3015 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003016 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003017 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003018 else
3019 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003020 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003021
Fred Drake12c6e2d1999-12-14 21:25:03 +00003022 return result;
3023}
3024#endif
3025
Guido van Rossumad0ee831995-03-01 10:34:45 +00003026#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003028"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003029Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Barry Warsaw53699e91996-12-10 23:23:01 +00003031static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003032posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003033{
Barry Warsaw53699e91996-12-10 23:23:01 +00003034 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003035}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003036#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003038
Guido van Rossumad0ee831995-03-01 10:34:45 +00003039#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003041"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003042Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043
Barry Warsaw53699e91996-12-10 23:23:01 +00003044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003045posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003046{
3047 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003048 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003049 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003050#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003051 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3052 APIRET rc;
3053 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003054 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003055
3056 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3057 APIRET rc;
3058 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003059 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003060
3061 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003062 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003063#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003064 if (kill(pid, sig) == -1)
3065 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003066#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003067 Py_INCREF(Py_None);
3068 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003069}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003070#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003071
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003072#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003073PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003074"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003075Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003076
3077static PyObject *
3078posix_killpg(PyObject *self, PyObject *args)
3079{
3080 int pgid, sig;
3081 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3082 return NULL;
3083 if (killpg(pgid, sig) == -1)
3084 return posix_error();
3085 Py_INCREF(Py_None);
3086 return Py_None;
3087}
3088#endif
3089
Guido van Rossumc0125471996-06-28 18:55:32 +00003090#ifdef HAVE_PLOCK
3091
3092#ifdef HAVE_SYS_LOCK_H
3093#include <sys/lock.h>
3094#endif
3095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003096PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003097"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003098Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003099
Barry Warsaw53699e91996-12-10 23:23:01 +00003100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003101posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003102{
3103 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003104 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003105 return NULL;
3106 if (plock(op) == -1)
3107 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003108 Py_INCREF(Py_None);
3109 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003110}
3111#endif
3112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003114#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003115PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003116"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003117Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003118
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003119#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003120#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003121static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003122async_system(const char *command)
3123{
3124 char *p, errormsg[256], args[1024];
3125 RESULTCODES rcodes;
3126 APIRET rc;
3127 char *shell = getenv("COMSPEC");
3128 if (!shell)
3129 shell = "cmd";
3130
3131 strcpy(args, shell);
3132 p = &args[ strlen(args)+1 ];
3133 strcpy(p, "/c ");
3134 strcat(p, command);
3135 p += strlen(p) + 1;
3136 *p = '\0';
3137
3138 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003139 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003140 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003141 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003142 &rcodes, shell);
3143 return rc;
3144}
3145
Guido van Rossumd48f2521997-12-05 22:19:34 +00003146static FILE *
3147popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003148{
3149 HFILE rhan, whan;
3150 FILE *retfd = NULL;
3151 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3152
Guido van Rossumd48f2521997-12-05 22:19:34 +00003153 if (rc != NO_ERROR) {
3154 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003155 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003156 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003157
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003158 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3159 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003160
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003161 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3162 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003163
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003164 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3165 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003166
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003167 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003168 }
3169
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003170 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3171 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003172
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003173 if (rc == NO_ERROR)
3174 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3175
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003176 close(oldfd); /* And Close Saved STDOUT Handle */
3177 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003178
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003179 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3180 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003181
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003182 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3183 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003184
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003185 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3186 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003187
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003188 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003189 }
3190
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003191 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3192 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003193
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003194 if (rc == NO_ERROR)
3195 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3196
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003197 close(oldfd); /* And Close Saved STDIN Handle */
3198 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003199
Guido van Rossumd48f2521997-12-05 22:19:34 +00003200 } else {
3201 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003202 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003203 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003204}
3205
3206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003207posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003208{
3209 char *name;
3210 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003211 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003212 FILE *fp;
3213 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003214 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003215 return NULL;
3216 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003217 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003218 Py_END_ALLOW_THREADS
3219 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003220 return os2_error(err);
3221
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003222 f = PyFile_FromFile(fp, name, mode, fclose);
3223 if (f != NULL)
3224 PyFile_SetBufSize(f, bufsize);
3225 return f;
3226}
3227
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003228#elif defined(PYCC_GCC)
3229
3230/* standard posix version of popen() support */
3231static PyObject *
3232posix_popen(PyObject *self, PyObject *args)
3233{
3234 char *name;
3235 char *mode = "r";
3236 int bufsize = -1;
3237 FILE *fp;
3238 PyObject *f;
3239 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3240 return NULL;
3241 Py_BEGIN_ALLOW_THREADS
3242 fp = popen(name, mode);
3243 Py_END_ALLOW_THREADS
3244 if (fp == NULL)
3245 return posix_error();
3246 f = PyFile_FromFile(fp, name, mode, pclose);
3247 if (f != NULL)
3248 PyFile_SetBufSize(f, bufsize);
3249 return f;
3250}
3251
3252/* fork() under OS/2 has lots'o'warts
3253 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3254 * most of this code is a ripoff of the win32 code, but using the
3255 * capabilities of EMX's C library routines
3256 */
3257
3258/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3259#define POPEN_1 1
3260#define POPEN_2 2
3261#define POPEN_3 3
3262#define POPEN_4 4
3263
3264static PyObject *_PyPopen(char *, int, int, int);
3265static int _PyPclose(FILE *file);
3266
3267/*
3268 * Internal dictionary mapping popen* file pointers to process handles,
3269 * for use when retrieving the process exit code. See _PyPclose() below
3270 * for more information on this dictionary's use.
3271 */
3272static PyObject *_PyPopenProcs = NULL;
3273
3274/* os2emx version of popen2()
3275 *
3276 * The result of this function is a pipe (file) connected to the
3277 * process's stdin, and a pipe connected to the process's stdout.
3278 */
3279
3280static PyObject *
3281os2emx_popen2(PyObject *self, PyObject *args)
3282{
3283 PyObject *f;
3284 int tm=0;
3285
3286 char *cmdstring;
3287 char *mode = "t";
3288 int bufsize = -1;
3289 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3290 return NULL;
3291
3292 if (*mode == 't')
3293 tm = O_TEXT;
3294 else if (*mode != 'b') {
3295 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3296 return NULL;
3297 } else
3298 tm = O_BINARY;
3299
3300 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3301
3302 return f;
3303}
3304
3305/*
3306 * Variation on os2emx.popen2
3307 *
3308 * The result of this function is 3 pipes - the process's stdin,
3309 * stdout and stderr
3310 */
3311
3312static PyObject *
3313os2emx_popen3(PyObject *self, PyObject *args)
3314{
3315 PyObject *f;
3316 int tm = 0;
3317
3318 char *cmdstring;
3319 char *mode = "t";
3320 int bufsize = -1;
3321 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3322 return NULL;
3323
3324 if (*mode == 't')
3325 tm = O_TEXT;
3326 else if (*mode != 'b') {
3327 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3328 return NULL;
3329 } else
3330 tm = O_BINARY;
3331
3332 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3333
3334 return f;
3335}
3336
3337/*
3338 * Variation on os2emx.popen2
3339 *
3340 * The result of this function is 2 pipes - the processes stdin,
3341 * and stdout+stderr combined as a single pipe.
3342 */
3343
3344static PyObject *
3345os2emx_popen4(PyObject *self, PyObject *args)
3346{
3347 PyObject *f;
3348 int tm = 0;
3349
3350 char *cmdstring;
3351 char *mode = "t";
3352 int bufsize = -1;
3353 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3354 return NULL;
3355
3356 if (*mode == 't')
3357 tm = O_TEXT;
3358 else if (*mode != 'b') {
3359 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3360 return NULL;
3361 } else
3362 tm = O_BINARY;
3363
3364 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3365
3366 return f;
3367}
3368
3369/* a couple of structures for convenient handling of multiple
3370 * file handles and pipes
3371 */
3372struct file_ref
3373{
3374 int handle;
3375 int flags;
3376};
3377
3378struct pipe_ref
3379{
3380 int rd;
3381 int wr;
3382};
3383
3384/* The following code is derived from the win32 code */
3385
3386static PyObject *
3387_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3388{
3389 struct file_ref stdio[3];
3390 struct pipe_ref p_fd[3];
3391 FILE *p_s[3];
3392 int file_count, i, pipe_err, pipe_pid;
3393 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3394 PyObject *f, *p_f[3];
3395
3396 /* file modes for subsequent fdopen's on pipe handles */
3397 if (mode == O_TEXT)
3398 {
3399 rd_mode = "rt";
3400 wr_mode = "wt";
3401 }
3402 else
3403 {
3404 rd_mode = "rb";
3405 wr_mode = "wb";
3406 }
3407
3408 /* prepare shell references */
3409 if ((shell = getenv("EMXSHELL")) == NULL)
3410 if ((shell = getenv("COMSPEC")) == NULL)
3411 {
3412 errno = ENOENT;
3413 return posix_error();
3414 }
3415
3416 sh_name = _getname(shell);
3417 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3418 opt = "/c";
3419 else
3420 opt = "-c";
3421
3422 /* save current stdio fds + their flags, and set not inheritable */
3423 i = pipe_err = 0;
3424 while (pipe_err >= 0 && i < 3)
3425 {
3426 pipe_err = stdio[i].handle = dup(i);
3427 stdio[i].flags = fcntl(i, F_GETFD, 0);
3428 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3429 i++;
3430 }
3431 if (pipe_err < 0)
3432 {
3433 /* didn't get them all saved - clean up and bail out */
3434 int saved_err = errno;
3435 while (i-- > 0)
3436 {
3437 close(stdio[i].handle);
3438 }
3439 errno = saved_err;
3440 return posix_error();
3441 }
3442
3443 /* create pipe ends */
3444 file_count = 2;
3445 if (n == POPEN_3)
3446 file_count = 3;
3447 i = pipe_err = 0;
3448 while ((pipe_err == 0) && (i < file_count))
3449 pipe_err = pipe((int *)&p_fd[i++]);
3450 if (pipe_err < 0)
3451 {
3452 /* didn't get them all made - clean up and bail out */
3453 while (i-- > 0)
3454 {
3455 close(p_fd[i].wr);
3456 close(p_fd[i].rd);
3457 }
3458 errno = EPIPE;
3459 return posix_error();
3460 }
3461
3462 /* change the actual standard IO streams over temporarily,
3463 * making the retained pipe ends non-inheritable
3464 */
3465 pipe_err = 0;
3466
3467 /* - stdin */
3468 if (dup2(p_fd[0].rd, 0) == 0)
3469 {
3470 close(p_fd[0].rd);
3471 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3472 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3473 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3474 {
3475 close(p_fd[0].wr);
3476 pipe_err = -1;
3477 }
3478 }
3479 else
3480 {
3481 pipe_err = -1;
3482 }
3483
3484 /* - stdout */
3485 if (pipe_err == 0)
3486 {
3487 if (dup2(p_fd[1].wr, 1) == 1)
3488 {
3489 close(p_fd[1].wr);
3490 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3491 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3492 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3493 {
3494 close(p_fd[1].rd);
3495 pipe_err = -1;
3496 }
3497 }
3498 else
3499 {
3500 pipe_err = -1;
3501 }
3502 }
3503
3504 /* - stderr, as required */
3505 if (pipe_err == 0)
3506 switch (n)
3507 {
3508 case POPEN_3:
3509 {
3510 if (dup2(p_fd[2].wr, 2) == 2)
3511 {
3512 close(p_fd[2].wr);
3513 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3514 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3515 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3516 {
3517 close(p_fd[2].rd);
3518 pipe_err = -1;
3519 }
3520 }
3521 else
3522 {
3523 pipe_err = -1;
3524 }
3525 break;
3526 }
3527
3528 case POPEN_4:
3529 {
3530 if (dup2(1, 2) != 2)
3531 {
3532 pipe_err = -1;
3533 }
3534 break;
3535 }
3536 }
3537
3538 /* spawn the child process */
3539 if (pipe_err == 0)
3540 {
3541 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3542 if (pipe_pid == -1)
3543 {
3544 pipe_err = -1;
3545 }
3546 else
3547 {
3548 /* save the PID into the FILE structure
3549 * NOTE: this implementation doesn't actually
3550 * take advantage of this, but do it for
3551 * completeness - AIM Apr01
3552 */
3553 for (i = 0; i < file_count; i++)
3554 p_s[i]->_pid = pipe_pid;
3555 }
3556 }
3557
3558 /* reset standard IO to normal */
3559 for (i = 0; i < 3; i++)
3560 {
3561 dup2(stdio[i].handle, i);
3562 fcntl(i, F_SETFD, stdio[i].flags);
3563 close(stdio[i].handle);
3564 }
3565
3566 /* if any remnant problems, clean up and bail out */
3567 if (pipe_err < 0)
3568 {
3569 for (i = 0; i < 3; i++)
3570 {
3571 close(p_fd[i].rd);
3572 close(p_fd[i].wr);
3573 }
3574 errno = EPIPE;
3575 return posix_error_with_filename(cmdstring);
3576 }
3577
3578 /* build tuple of file objects to return */
3579 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3580 PyFile_SetBufSize(p_f[0], bufsize);
3581 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3582 PyFile_SetBufSize(p_f[1], bufsize);
3583 if (n == POPEN_3)
3584 {
3585 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3586 PyFile_SetBufSize(p_f[0], bufsize);
3587 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3588 }
3589 else
3590 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3591
3592 /*
3593 * Insert the files we've created into the process dictionary
3594 * all referencing the list with the process handle and the
3595 * initial number of files (see description below in _PyPclose).
3596 * Since if _PyPclose later tried to wait on a process when all
3597 * handles weren't closed, it could create a deadlock with the
3598 * child, we spend some energy here to try to ensure that we
3599 * either insert all file handles into the dictionary or none
3600 * at all. It's a little clumsy with the various popen modes
3601 * and variable number of files involved.
3602 */
3603 if (!_PyPopenProcs)
3604 {
3605 _PyPopenProcs = PyDict_New();
3606 }
3607
3608 if (_PyPopenProcs)
3609 {
3610 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3611 int ins_rc[3];
3612
3613 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3614 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3615
3616 procObj = PyList_New(2);
3617 pidObj = PyInt_FromLong((long) pipe_pid);
3618 intObj = PyInt_FromLong((long) file_count);
3619
3620 if (procObj && pidObj && intObj)
3621 {
3622 PyList_SetItem(procObj, 0, pidObj);
3623 PyList_SetItem(procObj, 1, intObj);
3624
3625 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3626 if (fileObj[0])
3627 {
3628 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3629 fileObj[0],
3630 procObj);
3631 }
3632 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3633 if (fileObj[1])
3634 {
3635 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3636 fileObj[1],
3637 procObj);
3638 }
3639 if (file_count >= 3)
3640 {
3641 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3642 if (fileObj[2])
3643 {
3644 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3645 fileObj[2],
3646 procObj);
3647 }
3648 }
3649
3650 if (ins_rc[0] < 0 || !fileObj[0] ||
3651 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3652 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3653 {
3654 /* Something failed - remove any dictionary
3655 * entries that did make it.
3656 */
3657 if (!ins_rc[0] && fileObj[0])
3658 {
3659 PyDict_DelItem(_PyPopenProcs,
3660 fileObj[0]);
3661 }
3662 if (!ins_rc[1] && fileObj[1])
3663 {
3664 PyDict_DelItem(_PyPopenProcs,
3665 fileObj[1]);
3666 }
3667 if (!ins_rc[2] && fileObj[2])
3668 {
3669 PyDict_DelItem(_PyPopenProcs,
3670 fileObj[2]);
3671 }
3672 }
3673 }
3674
3675 /*
3676 * Clean up our localized references for the dictionary keys
3677 * and value since PyDict_SetItem will Py_INCREF any copies
3678 * that got placed in the dictionary.
3679 */
3680 Py_XDECREF(procObj);
3681 Py_XDECREF(fileObj[0]);
3682 Py_XDECREF(fileObj[1]);
3683 Py_XDECREF(fileObj[2]);
3684 }
3685
3686 /* Child is launched. */
3687 return f;
3688}
3689
3690/*
3691 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3692 * exit code for the child process and return as a result of the close.
3693 *
3694 * This function uses the _PyPopenProcs dictionary in order to map the
3695 * input file pointer to information about the process that was
3696 * originally created by the popen* call that created the file pointer.
3697 * The dictionary uses the file pointer as a key (with one entry
3698 * inserted for each file returned by the original popen* call) and a
3699 * single list object as the value for all files from a single call.
3700 * The list object contains the Win32 process handle at [0], and a file
3701 * count at [1], which is initialized to the total number of file
3702 * handles using that list.
3703 *
3704 * This function closes whichever handle it is passed, and decrements
3705 * the file count in the dictionary for the process handle pointed to
3706 * by this file. On the last close (when the file count reaches zero),
3707 * this function will wait for the child process and then return its
3708 * exit code as the result of the close() operation. This permits the
3709 * files to be closed in any order - it is always the close() of the
3710 * final handle that will return the exit code.
3711 */
3712
3713 /* RED_FLAG 31-Aug-2000 Tim
3714 * This is always called (today!) between a pair of
3715 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3716 * macros. So the thread running this has no valid thread state, as
3717 * far as Python is concerned. However, this calls some Python API
3718 * functions that cannot be called safely without a valid thread
3719 * state, in particular PyDict_GetItem.
3720 * As a temporary hack (although it may last for years ...), we
3721 * *rely* on not having a valid thread state in this function, in
3722 * order to create our own "from scratch".
3723 * This will deadlock if _PyPclose is ever called by a thread
3724 * holding the global lock.
3725 * (The OS/2 EMX thread support appears to cover the case where the
3726 * lock is already held - AIM Apr01)
3727 */
3728
3729static int _PyPclose(FILE *file)
3730{
3731 int result;
3732 int exit_code;
3733 int pipe_pid;
3734 PyObject *procObj, *pidObj, *intObj, *fileObj;
3735 int file_count;
3736#ifdef WITH_THREAD
3737 PyInterpreterState* pInterpreterState;
3738 PyThreadState* pThreadState;
3739#endif
3740
3741 /* Close the file handle first, to ensure it can't block the
3742 * child from exiting if it's the last handle.
3743 */
3744 result = fclose(file);
3745
3746#ifdef WITH_THREAD
3747 /* Bootstrap a valid thread state into existence. */
3748 pInterpreterState = PyInterpreterState_New();
3749 if (!pInterpreterState) {
3750 /* Well, we're hosed now! We don't have a thread
3751 * state, so can't call a nice error routine, or raise
3752 * an exception. Just die.
3753 */
3754 Py_FatalError("unable to allocate interpreter state "
3755 "when closing popen object.");
3756 return -1; /* unreachable */
3757 }
3758 pThreadState = PyThreadState_New(pInterpreterState);
3759 if (!pThreadState) {
3760 Py_FatalError("unable to allocate thread state "
3761 "when closing popen object.");
3762 return -1; /* unreachable */
3763 }
3764 /* Grab the global lock. Note that this will deadlock if the
3765 * current thread already has the lock! (see RED_FLAG comments
3766 * before this function)
3767 */
3768 PyEval_RestoreThread(pThreadState);
3769#endif
3770
3771 if (_PyPopenProcs)
3772 {
3773 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3774 (procObj = PyDict_GetItem(_PyPopenProcs,
3775 fileObj)) != NULL &&
3776 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3777 (intObj = PyList_GetItem(procObj,1)) != NULL)
3778 {
3779 pipe_pid = (int) PyInt_AsLong(pidObj);
3780 file_count = (int) PyInt_AsLong(intObj);
3781
3782 if (file_count > 1)
3783 {
3784 /* Still other files referencing process */
3785 file_count--;
3786 PyList_SetItem(procObj,1,
3787 PyInt_FromLong((long) file_count));
3788 }
3789 else
3790 {
3791 /* Last file for this process */
3792 if (result != EOF &&
3793 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3794 {
3795 /* extract exit status */
3796 if (WIFEXITED(exit_code))
3797 {
3798 result = WEXITSTATUS(exit_code);
3799 }
3800 else
3801 {
3802 errno = EPIPE;
3803 result = -1;
3804 }
3805 }
3806 else
3807 {
3808 /* Indicate failure - this will cause the file object
3809 * to raise an I/O error and translate the last
3810 * error code from errno. We do have a problem with
3811 * last errors that overlap the normal errno table,
3812 * but that's a consistent problem with the file object.
3813 */
3814 result = -1;
3815 }
3816 }
3817
3818 /* Remove this file pointer from dictionary */
3819 PyDict_DelItem(_PyPopenProcs, fileObj);
3820
3821 if (PyDict_Size(_PyPopenProcs) == 0)
3822 {
3823 Py_DECREF(_PyPopenProcs);
3824 _PyPopenProcs = NULL;
3825 }
3826
3827 } /* if object retrieval ok */
3828
3829 Py_XDECREF(fileObj);
3830 } /* if _PyPopenProcs */
3831
3832#ifdef WITH_THREAD
3833 /* Tear down the thread & interpreter states.
3834 * Note that interpreter state clear & delete functions automatically
3835 * call the thread clear & delete functions, and indeed insist on
3836 * doing that themselves. The lock must be held during the clear, but
3837 * need not be held during the delete.
3838 */
3839 PyInterpreterState_Clear(pInterpreterState);
3840 PyEval_ReleaseThread(pThreadState);
3841 PyInterpreterState_Delete(pInterpreterState);
3842#endif
3843
3844 return result;
3845}
3846
3847#endif /* PYCC_??? */
3848
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003849#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003850
3851/*
3852 * Portable 'popen' replacement for Win32.
3853 *
3854 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3855 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003856 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003857 */
3858
3859#include <malloc.h>
3860#include <io.h>
3861#include <fcntl.h>
3862
3863/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3864#define POPEN_1 1
3865#define POPEN_2 2
3866#define POPEN_3 3
3867#define POPEN_4 4
3868
3869static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003870static int _PyPclose(FILE *file);
3871
3872/*
3873 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003874 * for use when retrieving the process exit code. See _PyPclose() below
3875 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003876 */
3877static PyObject *_PyPopenProcs = NULL;
3878
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003879
3880/* popen that works from a GUI.
3881 *
3882 * The result of this function is a pipe (file) connected to the
3883 * processes stdin or stdout, depending on the requested mode.
3884 */
3885
3886static PyObject *
3887posix_popen(PyObject *self, PyObject *args)
3888{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003889 PyObject *f, *s;
3890 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003891
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003892 char *cmdstring;
3893 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003894 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003895 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003896 return NULL;
3897
3898 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003899
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003900 if (*mode == 'r')
3901 tm = _O_RDONLY;
3902 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003903 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003904 return NULL;
3905 } else
3906 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003907
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003908 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003909 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003910 return NULL;
3911 }
3912
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003913 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003914 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003915 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003916 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003917 else
3918 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3919
3920 return f;
3921}
3922
3923/* Variation on win32pipe.popen
3924 *
3925 * The result of this function is a pipe (file) connected to the
3926 * process's stdin, and a pipe connected to the process's stdout.
3927 */
3928
3929static PyObject *
3930win32_popen2(PyObject *self, PyObject *args)
3931{
3932 PyObject *f;
3933 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003934
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003935 char *cmdstring;
3936 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003937 int bufsize = -1;
3938 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003939 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003940
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003941 if (*mode == 't')
3942 tm = _O_TEXT;
3943 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003944 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945 return NULL;
3946 } else
3947 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003948
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003949 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003950 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003951 return NULL;
3952 }
3953
3954 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003955
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003956 return f;
3957}
3958
3959/*
3960 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003961 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003962 * The result of this function is 3 pipes - the process's stdin,
3963 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003964 */
3965
3966static PyObject *
3967win32_popen3(PyObject *self, PyObject *args)
3968{
3969 PyObject *f;
3970 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003971
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003972 char *cmdstring;
3973 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003974 int bufsize = -1;
3975 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003976 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003977
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 if (*mode == 't')
3979 tm = _O_TEXT;
3980 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003981 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003982 return NULL;
3983 } else
3984 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003985
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003986 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003987 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003988 return NULL;
3989 }
3990
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003991 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003992
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 return f;
3994}
3995
3996/*
3997 * Variation on win32pipe.popen
3998 *
Tim Peters5aa91602002-01-30 05:46:57 +00003999 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004000 * and stdout+stderr combined as a single pipe.
4001 */
4002
4003static PyObject *
4004win32_popen4(PyObject *self, PyObject *args)
4005{
4006 PyObject *f;
4007 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004008
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004009 char *cmdstring;
4010 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004011 int bufsize = -1;
4012 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004013 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004014
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004015 if (*mode == 't')
4016 tm = _O_TEXT;
4017 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004018 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 return NULL;
4020 } else
4021 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004022
4023 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004024 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004025 return NULL;
4026 }
4027
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004028 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004029
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004030 return f;
4031}
4032
Mark Hammond08501372001-01-31 07:30:29 +00004033static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004034_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004035 HANDLE hStdin,
4036 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004037 HANDLE hStderr,
4038 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004039{
4040 PROCESS_INFORMATION piProcInfo;
4041 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004042 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004043 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004044 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004045 int i;
4046 int x;
4047
4048 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004049 char *comshell;
4050
Tim Peters92e4dd82002-10-05 01:47:34 +00004051 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004052 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4053 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004054
4055 /* Explicitly check if we are using COMMAND.COM. If we are
4056 * then use the w9xpopen hack.
4057 */
4058 comshell = s1 + x;
4059 while (comshell >= s1 && *comshell != '\\')
4060 --comshell;
4061 ++comshell;
4062
4063 if (GetVersion() < 0x80000000 &&
4064 _stricmp(comshell, "command.com") != 0) {
4065 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004066 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004067 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004068 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004069 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004070 }
4071 else {
4072 /*
Tim Peters402d5982001-08-27 06:37:48 +00004073 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4074 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004075 */
Mark Hammond08501372001-01-31 07:30:29 +00004076 char modulepath[_MAX_PATH];
4077 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004078 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4079 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004080 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004081 x = i+1;
4082 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004083 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004084 strncat(modulepath,
4085 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004086 (sizeof(modulepath)/sizeof(modulepath[0]))
4087 -strlen(modulepath));
4088 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004089 /* Eeek - file-not-found - possibly an embedding
4090 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004091 */
Tim Peters5aa91602002-01-30 05:46:57 +00004092 strncpy(modulepath,
4093 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004094 sizeof(modulepath)/sizeof(modulepath[0]));
4095 if (modulepath[strlen(modulepath)-1] != '\\')
4096 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004097 strncat(modulepath,
4098 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004099 (sizeof(modulepath)/sizeof(modulepath[0]))
4100 -strlen(modulepath));
4101 /* No where else to look - raise an easily identifiable
4102 error, rather than leaving Windows to report
4103 "file not found" - as the user is probably blissfully
4104 unaware this shim EXE is used, and it will confuse them.
4105 (well, it confused me for a while ;-)
4106 */
4107 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004108 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004109 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004110 "for popen to work with your shell "
4111 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004112 szConsoleSpawn);
4113 return FALSE;
4114 }
4115 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004116 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004117 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004118 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004119
Tim Peters92e4dd82002-10-05 01:47:34 +00004120 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004121 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004122 /* To maintain correct argument passing semantics,
4123 we pass the command-line as it stands, and allow
4124 quoting to be applied. w9xpopen.exe will then
4125 use its argv vector, and re-quote the necessary
4126 args for the ultimate child process.
4127 */
Tim Peters75cdad52001-11-28 22:07:30 +00004128 PyOS_snprintf(
4129 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004130 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004132 s1,
4133 s3,
4134 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004135 /* Not passing CREATE_NEW_CONSOLE has been known to
4136 cause random failures on win9x. Specifically a
4137 dialog:
4138 "Your program accessed mem currently in use at xxx"
4139 and a hopeful warning about the stability of your
4140 system.
4141 Cost is Ctrl+C wont kill children, but anyone
4142 who cares can have a go!
4143 */
4144 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004145 }
4146 }
4147
4148 /* Could be an else here to try cmd.exe / command.com in the path
4149 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004150 else {
Tim Peters402d5982001-08-27 06:37:48 +00004151 PyErr_SetString(PyExc_RuntimeError,
4152 "Cannot locate a COMSPEC environment variable to "
4153 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004154 return FALSE;
4155 }
Tim Peters5aa91602002-01-30 05:46:57 +00004156
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004157 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4158 siStartInfo.cb = sizeof(STARTUPINFO);
4159 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4160 siStartInfo.hStdInput = hStdin;
4161 siStartInfo.hStdOutput = hStdout;
4162 siStartInfo.hStdError = hStderr;
4163 siStartInfo.wShowWindow = SW_HIDE;
4164
4165 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004166 s2,
4167 NULL,
4168 NULL,
4169 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004170 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004171 NULL,
4172 NULL,
4173 &siStartInfo,
4174 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004175 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004176 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004177
Mark Hammondb37a3732000-08-14 04:47:33 +00004178 /* Return process handle */
4179 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004180 return TRUE;
4181 }
Tim Peters402d5982001-08-27 06:37:48 +00004182 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004183 return FALSE;
4184}
4185
4186/* The following code is based off of KB: Q190351 */
4187
4188static PyObject *
4189_PyPopen(char *cmdstring, int mode, int n)
4190{
4191 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4192 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004193 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004195 SECURITY_ATTRIBUTES saAttr;
4196 BOOL fSuccess;
4197 int fd1, fd2, fd3;
4198 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004199 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004200 PyObject *f;
4201
4202 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4203 saAttr.bInheritHandle = TRUE;
4204 saAttr.lpSecurityDescriptor = NULL;
4205
4206 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4207 return win32_error("CreatePipe", NULL);
4208
4209 /* Create new output read handle and the input write handle. Set
4210 * the inheritance properties to FALSE. Otherwise, the child inherits
4211 * the these handles; resulting in non-closeable handles to the pipes
4212 * being created. */
4213 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004214 GetCurrentProcess(), &hChildStdinWrDup, 0,
4215 FALSE,
4216 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004217 if (!fSuccess)
4218 return win32_error("DuplicateHandle", NULL);
4219
4220 /* Close the inheritable version of ChildStdin
4221 that we're using. */
4222 CloseHandle(hChildStdinWr);
4223
4224 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4225 return win32_error("CreatePipe", NULL);
4226
4227 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004228 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4229 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004230 if (!fSuccess)
4231 return win32_error("DuplicateHandle", NULL);
4232
4233 /* Close the inheritable version of ChildStdout
4234 that we're using. */
4235 CloseHandle(hChildStdoutRd);
4236
4237 if (n != POPEN_4) {
4238 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4239 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004240 fSuccess = DuplicateHandle(GetCurrentProcess(),
4241 hChildStderrRd,
4242 GetCurrentProcess(),
4243 &hChildStderrRdDup, 0,
4244 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004245 if (!fSuccess)
4246 return win32_error("DuplicateHandle", NULL);
4247 /* Close the inheritable version of ChildStdErr that we're using. */
4248 CloseHandle(hChildStderrRd);
4249 }
Tim Peters5aa91602002-01-30 05:46:57 +00004250
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004251 switch (n) {
4252 case POPEN_1:
4253 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4254 case _O_WRONLY | _O_TEXT:
4255 /* Case for writing to child Stdin in text mode. */
4256 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4257 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004258 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004259 PyFile_SetBufSize(f, 0);
4260 /* We don't care about these pipes anymore, so close them. */
4261 CloseHandle(hChildStdoutRdDup);
4262 CloseHandle(hChildStderrRdDup);
4263 break;
4264
4265 case _O_RDONLY | _O_TEXT:
4266 /* Case for reading from child Stdout in text mode. */
4267 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4268 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004269 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 PyFile_SetBufSize(f, 0);
4271 /* We don't care about these pipes anymore, so close them. */
4272 CloseHandle(hChildStdinWrDup);
4273 CloseHandle(hChildStderrRdDup);
4274 break;
4275
4276 case _O_RDONLY | _O_BINARY:
4277 /* Case for readinig from child Stdout in binary mode. */
4278 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4279 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004280 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004281 PyFile_SetBufSize(f, 0);
4282 /* We don't care about these pipes anymore, so close them. */
4283 CloseHandle(hChildStdinWrDup);
4284 CloseHandle(hChildStderrRdDup);
4285 break;
4286
4287 case _O_WRONLY | _O_BINARY:
4288 /* Case for writing to child Stdin in binary mode. */
4289 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4290 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004291 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004292 PyFile_SetBufSize(f, 0);
4293 /* We don't care about these pipes anymore, so close them. */
4294 CloseHandle(hChildStdoutRdDup);
4295 CloseHandle(hChildStderrRdDup);
4296 break;
4297 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004298 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004299 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004300
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004301 case POPEN_2:
4302 case POPEN_4:
4303 {
4304 char *m1, *m2;
4305 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004306
Tim Peters7dca21e2002-08-19 00:42:29 +00004307 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004308 m1 = "r";
4309 m2 = "w";
4310 } else {
4311 m1 = "rb";
4312 m2 = "wb";
4313 }
4314
4315 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4316 f1 = _fdopen(fd1, m2);
4317 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4318 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004319 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004320 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004321 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004322 PyFile_SetBufSize(p2, 0);
4323
4324 if (n != 4)
4325 CloseHandle(hChildStderrRdDup);
4326
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004327 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004328 Py_XDECREF(p1);
4329 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004330 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004331 break;
4332 }
Tim Peters5aa91602002-01-30 05:46:57 +00004333
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004334 case POPEN_3:
4335 {
4336 char *m1, *m2;
4337 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004338
Tim Peters7dca21e2002-08-19 00:42:29 +00004339 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004340 m1 = "r";
4341 m2 = "w";
4342 } else {
4343 m1 = "rb";
4344 m2 = "wb";
4345 }
4346
4347 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4348 f1 = _fdopen(fd1, m2);
4349 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4350 f2 = _fdopen(fd2, m1);
4351 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4352 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004353 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004354 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4355 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004356 PyFile_SetBufSize(p1, 0);
4357 PyFile_SetBufSize(p2, 0);
4358 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004359 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004360 Py_XDECREF(p1);
4361 Py_XDECREF(p2);
4362 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004363 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004364 break;
4365 }
4366 }
4367
4368 if (n == POPEN_4) {
4369 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004370 hChildStdinRd,
4371 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004372 hChildStdoutWr,
4373 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004374 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004375 }
4376 else {
4377 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004378 hChildStdinRd,
4379 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004380 hChildStderrWr,
4381 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004382 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004383 }
4384
Mark Hammondb37a3732000-08-14 04:47:33 +00004385 /*
4386 * Insert the files we've created into the process dictionary
4387 * all referencing the list with the process handle and the
4388 * initial number of files (see description below in _PyPclose).
4389 * Since if _PyPclose later tried to wait on a process when all
4390 * handles weren't closed, it could create a deadlock with the
4391 * child, we spend some energy here to try to ensure that we
4392 * either insert all file handles into the dictionary or none
4393 * at all. It's a little clumsy with the various popen modes
4394 * and variable number of files involved.
4395 */
4396 if (!_PyPopenProcs) {
4397 _PyPopenProcs = PyDict_New();
4398 }
4399
4400 if (_PyPopenProcs) {
4401 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4402 int ins_rc[3];
4403
4404 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4405 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4406
4407 procObj = PyList_New(2);
4408 hProcessObj = PyLong_FromVoidPtr(hProcess);
4409 intObj = PyInt_FromLong(file_count);
4410
4411 if (procObj && hProcessObj && intObj) {
4412 PyList_SetItem(procObj,0,hProcessObj);
4413 PyList_SetItem(procObj,1,intObj);
4414
4415 fileObj[0] = PyLong_FromVoidPtr(f1);
4416 if (fileObj[0]) {
4417 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4418 fileObj[0],
4419 procObj);
4420 }
4421 if (file_count >= 2) {
4422 fileObj[1] = PyLong_FromVoidPtr(f2);
4423 if (fileObj[1]) {
4424 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4425 fileObj[1],
4426 procObj);
4427 }
4428 }
4429 if (file_count >= 3) {
4430 fileObj[2] = PyLong_FromVoidPtr(f3);
4431 if (fileObj[2]) {
4432 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4433 fileObj[2],
4434 procObj);
4435 }
4436 }
4437
4438 if (ins_rc[0] < 0 || !fileObj[0] ||
4439 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4440 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4441 /* Something failed - remove any dictionary
4442 * entries that did make it.
4443 */
4444 if (!ins_rc[0] && fileObj[0]) {
4445 PyDict_DelItem(_PyPopenProcs,
4446 fileObj[0]);
4447 }
4448 if (!ins_rc[1] && fileObj[1]) {
4449 PyDict_DelItem(_PyPopenProcs,
4450 fileObj[1]);
4451 }
4452 if (!ins_rc[2] && fileObj[2]) {
4453 PyDict_DelItem(_PyPopenProcs,
4454 fileObj[2]);
4455 }
4456 }
4457 }
Tim Peters5aa91602002-01-30 05:46:57 +00004458
Mark Hammondb37a3732000-08-14 04:47:33 +00004459 /*
4460 * Clean up our localized references for the dictionary keys
4461 * and value since PyDict_SetItem will Py_INCREF any copies
4462 * that got placed in the dictionary.
4463 */
4464 Py_XDECREF(procObj);
4465 Py_XDECREF(fileObj[0]);
4466 Py_XDECREF(fileObj[1]);
4467 Py_XDECREF(fileObj[2]);
4468 }
4469
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004470 /* Child is launched. Close the parents copy of those pipe
4471 * handles that only the child should have open. You need to
4472 * make sure that no handles to the write end of the output pipe
4473 * are maintained in this process or else the pipe will not close
4474 * when the child process exits and the ReadFile will hang. */
4475
4476 if (!CloseHandle(hChildStdinRd))
4477 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004478
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004479 if (!CloseHandle(hChildStdoutWr))
4480 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004481
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4483 return win32_error("CloseHandle", NULL);
4484
4485 return f;
4486}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004487
4488/*
4489 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4490 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004491 *
4492 * This function uses the _PyPopenProcs dictionary in order to map the
4493 * input file pointer to information about the process that was
4494 * originally created by the popen* call that created the file pointer.
4495 * The dictionary uses the file pointer as a key (with one entry
4496 * inserted for each file returned by the original popen* call) and a
4497 * single list object as the value for all files from a single call.
4498 * The list object contains the Win32 process handle at [0], and a file
4499 * count at [1], which is initialized to the total number of file
4500 * handles using that list.
4501 *
4502 * This function closes whichever handle it is passed, and decrements
4503 * the file count in the dictionary for the process handle pointed to
4504 * by this file. On the last close (when the file count reaches zero),
4505 * this function will wait for the child process and then return its
4506 * exit code as the result of the close() operation. This permits the
4507 * files to be closed in any order - it is always the close() of the
4508 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004509 */
Tim Peters736aa322000-09-01 06:51:24 +00004510
4511 /* RED_FLAG 31-Aug-2000 Tim
4512 * This is always called (today!) between a pair of
4513 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4514 * macros. So the thread running this has no valid thread state, as
4515 * far as Python is concerned. However, this calls some Python API
4516 * functions that cannot be called safely without a valid thread
4517 * state, in particular PyDict_GetItem.
4518 * As a temporary hack (although it may last for years ...), we
4519 * *rely* on not having a valid thread state in this function, in
4520 * order to create our own "from scratch".
4521 * This will deadlock if _PyPclose is ever called by a thread
4522 * holding the global lock.
4523 */
4524
Fredrik Lundh56055a42000-07-23 19:47:12 +00004525static int _PyPclose(FILE *file)
4526{
Fredrik Lundh20318932000-07-26 17:29:12 +00004527 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004528 DWORD exit_code;
4529 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004530 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4531 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004532#ifdef WITH_THREAD
4533 PyInterpreterState* pInterpreterState;
4534 PyThreadState* pThreadState;
4535#endif
4536
Fredrik Lundh20318932000-07-26 17:29:12 +00004537 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004538 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004539 */
4540 result = fclose(file);
4541
Tim Peters736aa322000-09-01 06:51:24 +00004542#ifdef WITH_THREAD
4543 /* Bootstrap a valid thread state into existence. */
4544 pInterpreterState = PyInterpreterState_New();
4545 if (!pInterpreterState) {
4546 /* Well, we're hosed now! We don't have a thread
4547 * state, so can't call a nice error routine, or raise
4548 * an exception. Just die.
4549 */
4550 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004551 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004552 return -1; /* unreachable */
4553 }
4554 pThreadState = PyThreadState_New(pInterpreterState);
4555 if (!pThreadState) {
4556 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004557 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004558 return -1; /* unreachable */
4559 }
4560 /* Grab the global lock. Note that this will deadlock if the
4561 * current thread already has the lock! (see RED_FLAG comments
4562 * before this function)
4563 */
4564 PyEval_RestoreThread(pThreadState);
4565#endif
4566
Fredrik Lundh56055a42000-07-23 19:47:12 +00004567 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004568 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4569 (procObj = PyDict_GetItem(_PyPopenProcs,
4570 fileObj)) != NULL &&
4571 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4572 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4573
4574 hProcess = PyLong_AsVoidPtr(hProcessObj);
4575 file_count = PyInt_AsLong(intObj);
4576
4577 if (file_count > 1) {
4578 /* Still other files referencing process */
4579 file_count--;
4580 PyList_SetItem(procObj,1,
4581 PyInt_FromLong(file_count));
4582 } else {
4583 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004584 if (result != EOF &&
4585 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4586 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004587 /* Possible truncation here in 16-bit environments, but
4588 * real exit codes are just the lower byte in any event.
4589 */
4590 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004591 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004592 /* Indicate failure - this will cause the file object
4593 * to raise an I/O error and translate the last Win32
4594 * error code from errno. We do have a problem with
4595 * last errors that overlap the normal errno table,
4596 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004597 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004598 if (result != EOF) {
4599 /* If the error wasn't from the fclose(), then
4600 * set errno for the file object error handling.
4601 */
4602 errno = GetLastError();
4603 }
4604 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004605 }
4606
4607 /* Free up the native handle at this point */
4608 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004609 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004610
Mark Hammondb37a3732000-08-14 04:47:33 +00004611 /* Remove this file pointer from dictionary */
4612 PyDict_DelItem(_PyPopenProcs, fileObj);
4613
4614 if (PyDict_Size(_PyPopenProcs) == 0) {
4615 Py_DECREF(_PyPopenProcs);
4616 _PyPopenProcs = NULL;
4617 }
4618
4619 } /* if object retrieval ok */
4620
4621 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004622 } /* if _PyPopenProcs */
4623
Tim Peters736aa322000-09-01 06:51:24 +00004624#ifdef WITH_THREAD
4625 /* Tear down the thread & interpreter states.
4626 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004627 * call the thread clear & delete functions, and indeed insist on
4628 * doing that themselves. The lock must be held during the clear, but
4629 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004630 */
4631 PyInterpreterState_Clear(pInterpreterState);
4632 PyEval_ReleaseThread(pThreadState);
4633 PyInterpreterState_Delete(pInterpreterState);
4634#endif
4635
Fredrik Lundh56055a42000-07-23 19:47:12 +00004636 return result;
4637}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004638
4639#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004641posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004642{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004643 char *name;
4644 char *mode = "r";
4645 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004646 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004648 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004649 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004650 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004651 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004652 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004653 if (fp == NULL)
4654 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004655 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004656 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004657 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004658 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004659}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004660
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004661#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004662#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004664
Guido van Rossumb6775db1994-08-01 11:34:53 +00004665#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004667"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004668Set the current process's user id.");
4669
Barry Warsaw53699e91996-12-10 23:23:01 +00004670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004671posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004672{
4673 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004674 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004675 return NULL;
4676 if (setuid(uid) < 0)
4677 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004678 Py_INCREF(Py_None);
4679 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004680}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004681#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004683
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004684#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004686"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004687Set the current process's effective user id.");
4688
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004689static PyObject *
4690posix_seteuid (PyObject *self, PyObject *args)
4691{
4692 int euid;
4693 if (!PyArg_ParseTuple(args, "i", &euid)) {
4694 return NULL;
4695 } else if (seteuid(euid) < 0) {
4696 return posix_error();
4697 } else {
4698 Py_INCREF(Py_None);
4699 return Py_None;
4700 }
4701}
4702#endif /* HAVE_SETEUID */
4703
4704#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004706"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004707Set the current process's effective group id.");
4708
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004709static PyObject *
4710posix_setegid (PyObject *self, PyObject *args)
4711{
4712 int egid;
4713 if (!PyArg_ParseTuple(args, "i", &egid)) {
4714 return NULL;
4715 } else if (setegid(egid) < 0) {
4716 return posix_error();
4717 } else {
4718 Py_INCREF(Py_None);
4719 return Py_None;
4720 }
4721}
4722#endif /* HAVE_SETEGID */
4723
4724#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004725PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004726"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004727Set the current process's real and effective user ids.");
4728
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004729static PyObject *
4730posix_setreuid (PyObject *self, PyObject *args)
4731{
4732 int ruid, euid;
4733 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4734 return NULL;
4735 } else if (setreuid(ruid, euid) < 0) {
4736 return posix_error();
4737 } else {
4738 Py_INCREF(Py_None);
4739 return Py_None;
4740 }
4741}
4742#endif /* HAVE_SETREUID */
4743
4744#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004746"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004747Set the current process's real and effective group ids.");
4748
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004749static PyObject *
4750posix_setregid (PyObject *self, PyObject *args)
4751{
4752 int rgid, egid;
4753 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4754 return NULL;
4755 } else if (setregid(rgid, egid) < 0) {
4756 return posix_error();
4757 } else {
4758 Py_INCREF(Py_None);
4759 return Py_None;
4760 }
4761}
4762#endif /* HAVE_SETREGID */
4763
Guido van Rossumb6775db1994-08-01 11:34:53 +00004764#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004765PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004766"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004767Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004768
Barry Warsaw53699e91996-12-10 23:23:01 +00004769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004770posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004771{
4772 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004773 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004774 return NULL;
4775 if (setgid(gid) < 0)
4776 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004777 Py_INCREF(Py_None);
4778 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004779}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004780#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004781
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004782#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004784"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004785Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004786
4787static PyObject *
4788posix_setgroups(PyObject *self, PyObject *args)
4789{
4790 PyObject *groups;
4791 int i, len;
4792 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004793
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004794 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4795 return NULL;
4796 if (!PySequence_Check(groups)) {
4797 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4798 return NULL;
4799 }
4800 len = PySequence_Size(groups);
4801 if (len > MAX_GROUPS) {
4802 PyErr_SetString(PyExc_ValueError, "too many groups");
4803 return NULL;
4804 }
4805 for(i = 0; i < len; i++) {
4806 PyObject *elem;
4807 elem = PySequence_GetItem(groups, i);
4808 if (!elem)
4809 return NULL;
4810 if (!PyInt_Check(elem)) {
4811 PyErr_SetString(PyExc_TypeError,
4812 "groups must be integers");
4813 Py_DECREF(elem);
4814 return NULL;
4815 }
4816 /* XXX: check that value fits into gid_t. */
4817 grouplist[i] = PyInt_AsLong(elem);
4818 Py_DECREF(elem);
4819 }
4820
4821 if (setgroups(len, grouplist) < 0)
4822 return posix_error();
4823 Py_INCREF(Py_None);
4824 return Py_None;
4825}
4826#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004827
Guido van Rossumb6775db1994-08-01 11:34:53 +00004828#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004830"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004832
Barry Warsaw53699e91996-12-10 23:23:01 +00004833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004834posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004835{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004836 int pid, options;
4837#ifdef UNION_WAIT
4838 union wait status;
4839#define status_i (status.w_status)
4840#else
4841 int status;
4842#define status_i status
4843#endif
4844 status_i = 0;
4845
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004846 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004847 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004848 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004849 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004850 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004851 if (pid == -1)
4852 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004853 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004854 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004855}
4856
Tim Petersab034fa2002-02-01 11:27:43 +00004857#elif defined(HAVE_CWAIT)
4858
4859/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004860PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004861"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004862"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004863
4864static PyObject *
4865posix_waitpid(PyObject *self, PyObject *args)
4866{
4867 int pid, options;
4868 int status;
4869
4870 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4871 return NULL;
4872 Py_BEGIN_ALLOW_THREADS
4873 pid = _cwait(&status, pid, options);
4874 Py_END_ALLOW_THREADS
4875 if (pid == -1)
4876 return posix_error();
4877 else
4878 /* shift the status left a byte so this is more like the
4879 POSIX waitpid */
4880 return Py_BuildValue("ii", pid, status << 8);
4881}
4882#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004883
Guido van Rossumad0ee831995-03-01 10:34:45 +00004884#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004886"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004890posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004891{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004892 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004893#ifdef UNION_WAIT
4894 union wait status;
4895#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004896#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004897 int status;
4898#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004899#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004900
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004901 status_i = 0;
4902 Py_BEGIN_ALLOW_THREADS
4903 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004905 if (pid == -1)
4906 return posix_error();
4907 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004908 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004909#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004910}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004911#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004915"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004917
Barry Warsaw53699e91996-12-10 23:23:01 +00004918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004919posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004920{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004921#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004922 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004923#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004924#ifdef MS_WINDOWS
4925 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4926#else
4927 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4928#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004929#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004930}
4931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Guido van Rossumb6775db1994-08-01 11:34:53 +00004933#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004935"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004937
Barry Warsaw53699e91996-12-10 23:23:01 +00004938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004939posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004940{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004941 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004942 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004943 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004944 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004945 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004946 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004947 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004948 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004949 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004950 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004951 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004952}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004953#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004955
Guido van Rossumb6775db1994-08-01 11:34:53 +00004956#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004957PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004958"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004960
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004962posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004963{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004964 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004965}
4966#endif /* HAVE_SYMLINK */
4967
4968
4969#ifdef HAVE_TIMES
4970#ifndef HZ
4971#define HZ 60 /* Universal constant :-) */
4972#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004973
Guido van Rossumd48f2521997-12-05 22:19:34 +00004974#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4975static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004976system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004977{
4978 ULONG value = 0;
4979
4980 Py_BEGIN_ALLOW_THREADS
4981 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4982 Py_END_ALLOW_THREADS
4983
4984 return value;
4985}
4986
4987static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004988posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004989{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004990 /* Currently Only Uptime is Provided -- Others Later */
4991 return Py_BuildValue("ddddd",
4992 (double)0 /* t.tms_utime / HZ */,
4993 (double)0 /* t.tms_stime / HZ */,
4994 (double)0 /* t.tms_cutime / HZ */,
4995 (double)0 /* t.tms_cstime / HZ */,
4996 (double)system_uptime() / 1000);
4997}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004998#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004999static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005000posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005001{
5002 struct tms t;
5003 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005004 errno = 0;
5005 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 if (c == (clock_t) -1)
5007 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005008 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005009 (double)t.tms_utime / HZ,
5010 (double)t.tms_stime / HZ,
5011 (double)t.tms_cutime / HZ,
5012 (double)t.tms_cstime / HZ,
5013 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005014}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005015#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005016#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005017
5018
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005019#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005020#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005021static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005022posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005023{
5024 FILETIME create, exit, kernel, user;
5025 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005026 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005027 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5028 /* The fields of a FILETIME structure are the hi and lo part
5029 of a 64-bit value expressed in 100 nanosecond units.
5030 1e7 is one second in such units; 1e-7 the inverse.
5031 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5032 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005033 return Py_BuildValue(
5034 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005035 (double)(kernel.dwHighDateTime*429.4967296 +
5036 kernel.dwLowDateTime*1e-7),
5037 (double)(user.dwHighDateTime*429.4967296 +
5038 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005039 (double)0,
5040 (double)0,
5041 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005042}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005043#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005044
5045#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005047"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005048Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005049#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005051
Guido van Rossumb6775db1994-08-01 11:34:53 +00005052#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005054"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005055Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005056
Barry Warsaw53699e91996-12-10 23:23:01 +00005057static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005058posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005059{
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 if (setsid() < 0)
5061 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005062 Py_INCREF(Py_None);
5063 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005064}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005065#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005066
Guido van Rossumb6775db1994-08-01 11:34:53 +00005067#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005069"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005070Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005071
Barry Warsaw53699e91996-12-10 23:23:01 +00005072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005073posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005074{
5075 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005076 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005077 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005078 if (setpgid(pid, pgrp) < 0)
5079 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005080 Py_INCREF(Py_None);
5081 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005083#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Guido van Rossumb6775db1994-08-01 11:34:53 +00005086#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005088"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005089Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005090
Barry Warsaw53699e91996-12-10 23:23:01 +00005091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005092posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005093{
5094 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005095 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005096 return NULL;
5097 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005098 if (pgid < 0)
5099 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005100 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005101}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005102#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005104
Guido van Rossumb6775db1994-08-01 11:34:53 +00005105#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005107"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005108Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005109
Barry Warsaw53699e91996-12-10 23:23:01 +00005110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005111posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005112{
5113 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005114 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005115 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005116 if (tcsetpgrp(fd, pgid) < 0)
5117 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005118 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005119 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005120}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005121#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005122
Guido van Rossum687dd131993-05-17 08:34:16 +00005123/* Functions acting on file descriptors */
5124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005126"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005127Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005128
Barry Warsaw53699e91996-12-10 23:23:01 +00005129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005130posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005131{
Mark Hammondef8b6542001-05-13 08:04:26 +00005132 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005133 int flag;
5134 int mode = 0777;
5135 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005136
5137#ifdef MS_WINDOWS
5138 if (unicode_file_names()) {
5139 PyUnicodeObject *po;
5140 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5141 Py_BEGIN_ALLOW_THREADS
5142 /* PyUnicode_AS_UNICODE OK without thread
5143 lock as it is a simple dereference. */
5144 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5145 Py_END_ALLOW_THREADS
5146 if (fd < 0)
5147 return posix_error();
5148 return PyInt_FromLong((long)fd);
5149 }
5150 /* Drop the argument parsing error as narrow strings
5151 are also valid. */
5152 PyErr_Clear();
5153 }
5154#endif
5155
Tim Peters5aa91602002-01-30 05:46:57 +00005156 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005157 Py_FileSystemDefaultEncoding, &file,
5158 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005159 return NULL;
5160
Barry Warsaw53699e91996-12-10 23:23:01 +00005161 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005162 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005163 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005164 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005165 return posix_error_with_allocated_filename(file);
5166 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005167 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005168}
5169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005171PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005172"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005173Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005174
Barry Warsaw53699e91996-12-10 23:23:01 +00005175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005176posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005177{
5178 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005179 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005180 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005181 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005182 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005184 if (res < 0)
5185 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 Py_INCREF(Py_None);
5187 return Py_None;
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_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005193Return a duplicate of a file descriptor.");
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_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005197{
5198 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199 if (!PyArg_ParseTuple(args, "i:dup", &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 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005203 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005204 if (fd < 0)
5205 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005206 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005207}
5208
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005209
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005211"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005213
Barry Warsaw53699e91996-12-10 23:23:01 +00005214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005216{
5217 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005218 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005219 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005220 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005221 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005222 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005223 if (res < 0)
5224 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005225 Py_INCREF(Py_None);
5226 return Py_None;
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_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005231"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232Set the current position of a 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_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005236{
5237 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005238#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005239 LONG_LONG pos, res;
5240#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005241 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005242#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005243 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005245 return NULL;
5246#ifdef SEEK_SET
5247 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5248 switch (how) {
5249 case 0: how = SEEK_SET; break;
5250 case 1: how = SEEK_CUR; break;
5251 case 2: how = SEEK_END; break;
5252 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005253#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005254
5255#if !defined(HAVE_LARGEFILE_SUPPORT)
5256 pos = PyInt_AsLong(posobj);
5257#else
5258 pos = PyLong_Check(posobj) ?
5259 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5260#endif
5261 if (PyErr_Occurred())
5262 return NULL;
5263
Barry Warsaw53699e91996-12-10 23:23:01 +00005264 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005265#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005266 res = _lseeki64(fd, pos, how);
5267#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005268 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005269#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005270 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005271 if (res < 0)
5272 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005273
5274#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005275 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005276#else
5277 return PyLong_FromLongLong(res);
5278#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005279}
5280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005283"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005284Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005285
Barry Warsaw53699e91996-12-10 23:23:01 +00005286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005287posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005288{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005289 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005290 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005291 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005292 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005293 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005294 if (buffer == NULL)
5295 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005296 Py_BEGIN_ALLOW_THREADS
5297 n = read(fd, PyString_AsString(buffer), size);
5298 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005299 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005300 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005301 return posix_error();
5302 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005303 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005304 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005305 return buffer;
5306}
5307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005310"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005311Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005312
Barry Warsaw53699e91996-12-10 23:23:01 +00005313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005314posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005315{
5316 int fd, size;
5317 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005318 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005320 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005321 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005322 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005323 if (size < 0)
5324 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005325 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005326}
5327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005330"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331Like stat(), but for an open 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_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005335{
5336 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005337 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005338 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005340 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005341 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005342 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005343 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005344 if (res != 0)
5345 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005346
Fred Drake699f3522000-06-29 21:12:41 +00005347 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005348}
5349
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005352"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005354
Barry Warsaw53699e91996-12-10 23:23:01 +00005355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005356posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005357{
Guido van Rossum687dd131993-05-17 08:34:16 +00005358 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005359 char *mode = "r";
5360 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005361 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005362 PyObject *f;
5363 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005364 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005365
Thomas Heller1f043e22002-11-07 16:00:59 +00005366 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5367 PyErr_Format(PyExc_ValueError,
5368 "invalid file mode '%s'", mode);
5369 return NULL;
5370 }
5371
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005373 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005374 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005375 if (fp == NULL)
5376 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005377 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005378 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005379 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005380 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005381}
5382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005384"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005385Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005387
5388static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005389posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005390{
5391 int fd;
5392 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5393 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005394 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005395}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005396
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005397#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005399"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005401
Barry Warsaw53699e91996-12-10 23:23:01 +00005402static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005403posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005404{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005405#if defined(PYOS_OS2)
5406 HFILE read, write;
5407 APIRET rc;
5408
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005409 Py_BEGIN_ALLOW_THREADS
5410 rc = DosCreatePipe( &read, &write, 4096);
5411 Py_END_ALLOW_THREADS
5412 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005413 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005414
5415 return Py_BuildValue("(ii)", read, write);
5416#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005417#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005418 int fds[2];
5419 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005420 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005421#if defined(__VMS)
5422 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5423#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005424 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005425#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005426 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005427 if (res != 0)
5428 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005429 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005430#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005431 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005432 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005433 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005434 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005435 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005436 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005437 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005438 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005439 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5440 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005441 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005442#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005443#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005444}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005445#endif /* HAVE_PIPE */
5446
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005447
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005448#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005449PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005450"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005451Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005452
Barry Warsaw53699e91996-12-10 23:23:01 +00005453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005454posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005455{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005456 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005457 int mode = 0666;
5458 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005459 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005460 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005461 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005462 res = mkfifo(filename, mode);
5463 Py_END_ALLOW_THREADS
5464 if (res < 0)
5465 return posix_error();
5466 Py_INCREF(Py_None);
5467 return Py_None;
5468}
5469#endif
5470
5471
Neal Norwitz11690112002-07-30 01:08:28 +00005472#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005474"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005475Create a filesystem node (file, device special file or named pipe)\n\
5476named filename. mode specifies both the permissions to use and the\n\
5477type of node to be created, being combined (bitwise OR) with one of\n\
5478S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005479device defines the newly created device special file (probably using\n\
5480os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005481
5482
5483static PyObject *
5484posix_mknod(PyObject *self, PyObject *args)
5485{
5486 char *filename;
5487 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005488 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005489 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005490 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005491 return NULL;
5492 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005493 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005494 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005495 if (res < 0)
5496 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005497 Py_INCREF(Py_None);
5498 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005499}
5500#endif
5501
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005502#ifdef HAVE_DEVICE_MACROS
5503PyDoc_STRVAR(posix_major__doc__,
5504"major(device) -> major number\n\
5505Extracts a device major number from a raw device number.");
5506
5507static PyObject *
5508posix_major(PyObject *self, PyObject *args)
5509{
5510 int device;
5511 if (!PyArg_ParseTuple(args, "i:major", &device))
5512 return NULL;
5513 return PyInt_FromLong((long)major(device));
5514}
5515
5516PyDoc_STRVAR(posix_minor__doc__,
5517"minor(device) -> minor number\n\
5518Extracts a device minor number from a raw device number.");
5519
5520static PyObject *
5521posix_minor(PyObject *self, PyObject *args)
5522{
5523 int device;
5524 if (!PyArg_ParseTuple(args, "i:minor", &device))
5525 return NULL;
5526 return PyInt_FromLong((long)minor(device));
5527}
5528
5529PyDoc_STRVAR(posix_makedev__doc__,
5530"makedev(major, minor) -> device number\n\
5531Composes a raw device number from the major and minor device numbers.");
5532
5533static PyObject *
5534posix_makedev(PyObject *self, PyObject *args)
5535{
5536 int major, minor;
5537 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5538 return NULL;
5539 return PyInt_FromLong((long)makedev(major, minor));
5540}
5541#endif /* device macros */
5542
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005543
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005544#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005545PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005546"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005548
Barry Warsaw53699e91996-12-10 23:23:01 +00005549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005550posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005551{
5552 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005553 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005554 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005555 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005556
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005557 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005558 return NULL;
5559
5560#if !defined(HAVE_LARGEFILE_SUPPORT)
5561 length = PyInt_AsLong(lenobj);
5562#else
5563 length = PyLong_Check(lenobj) ?
5564 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5565#endif
5566 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005567 return NULL;
5568
Barry Warsaw53699e91996-12-10 23:23:01 +00005569 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005570 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005571 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005572 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005574 return NULL;
5575 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_INCREF(Py_None);
5577 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005578}
5579#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005580
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005581#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005583"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005584Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Fred Drake762e2061999-08-26 17:23:54 +00005586/* Save putenv() parameters as values here, so we can collect them when they
5587 * get re-set with another call for the same key. */
5588static PyObject *posix_putenv_garbage;
5589
Tim Peters5aa91602002-01-30 05:46:57 +00005590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005592{
5593 char *s1, *s2;
5594 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005595 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005596 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005597
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005598 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005599 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005600
5601#if defined(PYOS_OS2)
5602 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5603 APIRET rc;
5604
5605 if (strlen(s2) == 0) /* If New Value is an Empty String */
5606 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5607
5608 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5609 if (rc != NO_ERROR)
5610 return os2_error(rc);
5611
5612 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5613 APIRET rc;
5614
5615 if (strlen(s2) == 0) /* If New Value is an Empty String */
5616 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5617
5618 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5619 if (rc != NO_ERROR)
5620 return os2_error(rc);
5621 } else {
5622#endif
5623
Fred Drake762e2061999-08-26 17:23:54 +00005624 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005625 len = strlen(s1) + strlen(s2) + 2;
5626 /* len includes space for a trailing \0; the size arg to
5627 PyString_FromStringAndSize does not count that */
5628 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005629 if (newstr == NULL)
5630 return PyErr_NoMemory();
5631 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005632 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005633 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005634 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005635 posix_error();
5636 return NULL;
5637 }
Fred Drake762e2061999-08-26 17:23:54 +00005638 /* Install the first arg and newstr in posix_putenv_garbage;
5639 * this will cause previous value to be collected. This has to
5640 * happen after the real putenv() call because the old value
5641 * was still accessible until then. */
5642 if (PyDict_SetItem(posix_putenv_garbage,
5643 PyTuple_GET_ITEM(args, 0), newstr)) {
5644 /* really not much we can do; just leak */
5645 PyErr_Clear();
5646 }
5647 else {
5648 Py_DECREF(newstr);
5649 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005650
5651#if defined(PYOS_OS2)
5652 }
5653#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005654 Py_INCREF(Py_None);
5655 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005656}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005657#endif /* putenv */
5658
Guido van Rossumc524d952001-10-19 01:31:59 +00005659#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005661"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005662Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005663
5664static PyObject *
5665posix_unsetenv(PyObject *self, PyObject *args)
5666{
5667 char *s1;
5668
5669 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5670 return NULL;
5671
5672 unsetenv(s1);
5673
5674 /* Remove the key from posix_putenv_garbage;
5675 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005676 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005677 * old value was still accessible until then.
5678 */
5679 if (PyDict_DelItem(posix_putenv_garbage,
5680 PyTuple_GET_ITEM(args, 0))) {
5681 /* really not much we can do; just leak */
5682 PyErr_Clear();
5683 }
5684
5685 Py_INCREF(Py_None);
5686 return Py_None;
5687}
5688#endif /* unsetenv */
5689
Guido van Rossumb6a47161997-09-15 22:54:34 +00005690#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005692"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005694
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005696posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005697{
5698 int code;
5699 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005701 return NULL;
5702 message = strerror(code);
5703 if (message == NULL) {
5704 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005705 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005706 return NULL;
5707 }
5708 return PyString_FromString(message);
5709}
5710#endif /* strerror */
5711
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005712
Guido van Rossumc9641791998-08-04 15:26:23 +00005713#ifdef HAVE_SYS_WAIT_H
5714
Fred Drake106c1a02002-04-23 15:58:02 +00005715#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005717"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005719
5720static PyObject *
5721posix_WCOREDUMP(PyObject *self, PyObject *args)
5722{
5723#ifdef UNION_WAIT
5724 union wait status;
5725#define status_i (status.w_status)
5726#else
5727 int status;
5728#define status_i status
5729#endif
5730 status_i = 0;
5731
5732 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5733 {
5734 return NULL;
5735 }
5736
5737 return PyBool_FromLong(WCOREDUMP(status));
5738#undef status_i
5739}
5740#endif /* WCOREDUMP */
5741
5742#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005743PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005744"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005745Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005746job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005747
5748static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005749posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005750{
5751#ifdef UNION_WAIT
5752 union wait status;
5753#define status_i (status.w_status)
5754#else
5755 int status;
5756#define status_i status
5757#endif
5758 status_i = 0;
5759
5760 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5761 {
5762 return NULL;
5763 }
5764
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005765 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005766#undef status_i
5767}
5768#endif /* WIFCONTINUED */
5769
Guido van Rossumc9641791998-08-04 15:26:23 +00005770#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005772"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005773Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005774
5775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005776posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005777{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005778#ifdef UNION_WAIT
5779 union wait status;
5780#define status_i (status.w_status)
5781#else
5782 int status;
5783#define status_i status
5784#endif
5785 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005786
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005787 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005788 {
5789 return NULL;
5790 }
Tim Peters5aa91602002-01-30 05:46:57 +00005791
Fred Drake106c1a02002-04-23 15:58:02 +00005792 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005793#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005794}
5795#endif /* WIFSTOPPED */
5796
5797#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005799"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005800Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005801
5802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005803posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005804{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005805#ifdef UNION_WAIT
5806 union wait status;
5807#define status_i (status.w_status)
5808#else
5809 int status;
5810#define status_i status
5811#endif
5812 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005813
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005814 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005815 {
5816 return NULL;
5817 }
Tim Peters5aa91602002-01-30 05:46:57 +00005818
Fred Drake106c1a02002-04-23 15:58:02 +00005819 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005820#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005821}
5822#endif /* WIFSIGNALED */
5823
5824#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005825PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005826"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005827Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005829
5830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005831posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005832{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005833#ifdef UNION_WAIT
5834 union wait status;
5835#define status_i (status.w_status)
5836#else
5837 int status;
5838#define status_i status
5839#endif
5840 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005841
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005842 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005843 {
5844 return NULL;
5845 }
Tim Peters5aa91602002-01-30 05:46:57 +00005846
Fred Drake106c1a02002-04-23 15:58:02 +00005847 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005848#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005849}
5850#endif /* WIFEXITED */
5851
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005852#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005854"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005855Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005856
5857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005858posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005859{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005860#ifdef UNION_WAIT
5861 union wait status;
5862#define status_i (status.w_status)
5863#else
5864 int status;
5865#define status_i status
5866#endif
5867 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005868
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005869 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005870 {
5871 return NULL;
5872 }
Tim Peters5aa91602002-01-30 05:46:57 +00005873
Guido van Rossumc9641791998-08-04 15:26:23 +00005874 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005875#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005876}
5877#endif /* WEXITSTATUS */
5878
5879#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005880PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005881"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005882Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005883value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005884
5885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005886posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005887{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005888#ifdef UNION_WAIT
5889 union wait status;
5890#define status_i (status.w_status)
5891#else
5892 int status;
5893#define status_i status
5894#endif
5895 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005896
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005897 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005898 {
5899 return NULL;
5900 }
Tim Peters5aa91602002-01-30 05:46:57 +00005901
Guido van Rossumc9641791998-08-04 15:26:23 +00005902 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005903#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005904}
5905#endif /* WTERMSIG */
5906
5907#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005909"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005910Return the signal that stopped the process that provided\n\
5911the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005912
5913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005914posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005915{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005916#ifdef UNION_WAIT
5917 union wait status;
5918#define status_i (status.w_status)
5919#else
5920 int status;
5921#define status_i status
5922#endif
5923 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005924
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005925 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005926 {
5927 return NULL;
5928 }
Tim Peters5aa91602002-01-30 05:46:57 +00005929
Guido van Rossumc9641791998-08-04 15:26:23 +00005930 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005931#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005932}
5933#endif /* WSTOPSIG */
5934
5935#endif /* HAVE_SYS_WAIT_H */
5936
5937
Guido van Rossum94f6f721999-01-06 18:42:14 +00005938#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005939#ifdef _SCO_DS
5940/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5941 needed definitions in sys/statvfs.h */
5942#define _SVID3
5943#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005944#include <sys/statvfs.h>
5945
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005946static PyObject*
5947_pystatvfs_fromstructstatvfs(struct statvfs st) {
5948 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5949 if (v == NULL)
5950 return NULL;
5951
5952#if !defined(HAVE_LARGEFILE_SUPPORT)
5953 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5954 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5955 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5956 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5957 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5958 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5959 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5960 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5961 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5962 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5963#else
5964 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5965 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005966 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005967 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005968 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005969 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5970 PyStructSequence_SET_ITEM(v, 4,
5971 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005972 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005973 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005974 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005975 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005976 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005977 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5978 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5979 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5980#endif
5981
5982 return v;
5983}
5984
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005986"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005988
5989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005990posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005991{
5992 int fd, res;
5993 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005994
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005995 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005996 return NULL;
5997 Py_BEGIN_ALLOW_THREADS
5998 res = fstatvfs(fd, &st);
5999 Py_END_ALLOW_THREADS
6000 if (res != 0)
6001 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006002
6003 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006004}
6005#endif /* HAVE_FSTATVFS */
6006
6007
6008#if defined(HAVE_STATVFS)
6009#include <sys/statvfs.h>
6010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006014
6015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006017{
6018 char *path;
6019 int res;
6020 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006021 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006022 return NULL;
6023 Py_BEGIN_ALLOW_THREADS
6024 res = statvfs(path, &st);
6025 Py_END_ALLOW_THREADS
6026 if (res != 0)
6027 return posix_error_with_filename(path);
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_STATVFS */
6032
6033
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006034#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006036"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006037Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006038The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006040
6041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006042posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006043{
6044 PyObject *result = NULL;
6045 char *dir = NULL;
6046 char *pfx = NULL;
6047 char *name;
6048
6049 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6050 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006051
6052 if (PyErr_Warn(PyExc_RuntimeWarning,
6053 "tempnam is a potential security risk to your program") < 0)
6054 return NULL;
6055
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006056#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006057 name = _tempnam(dir, pfx);
6058#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006059 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006060#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006061 if (name == NULL)
6062 return PyErr_NoMemory();
6063 result = PyString_FromString(name);
6064 free(name);
6065 return result;
6066}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006067#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006068
6069
6070#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006072"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006074
6075static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006076posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006077{
6078 FILE *fp;
6079
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006080 fp = tmpfile();
6081 if (fp == NULL)
6082 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006083 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006084}
6085#endif
6086
6087
6088#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006090"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006091Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006092
6093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006094posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006095{
6096 char buffer[L_tmpnam];
6097 char *name;
6098
Skip Montanaro95618b52001-08-18 18:52:10 +00006099 if (PyErr_Warn(PyExc_RuntimeWarning,
6100 "tmpnam is a potential security risk to your program") < 0)
6101 return NULL;
6102
Greg Wardb48bc172000-03-01 21:51:56 +00006103#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006104 name = tmpnam_r(buffer);
6105#else
6106 name = tmpnam(buffer);
6107#endif
6108 if (name == NULL) {
6109 PyErr_SetObject(PyExc_OSError,
6110 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006111#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112 "unexpected NULL from tmpnam_r"
6113#else
6114 "unexpected NULL from tmpnam"
6115#endif
6116 ));
6117 return NULL;
6118 }
6119 return PyString_FromString(buffer);
6120}
6121#endif
6122
6123
Fred Drakec9680921999-12-13 16:37:25 +00006124/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6125 * It maps strings representing configuration variable names to
6126 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006127 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006128 * rarely-used constants. There are three separate tables that use
6129 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006130 *
6131 * This code is always included, even if none of the interfaces that
6132 * need it are included. The #if hackery needed to avoid it would be
6133 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006134 */
6135struct constdef {
6136 char *name;
6137 long value;
6138};
6139
Fred Drake12c6e2d1999-12-14 21:25:03 +00006140static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006141conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6142 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006143{
6144 if (PyInt_Check(arg)) {
6145 *valuep = PyInt_AS_LONG(arg);
6146 return 1;
6147 }
6148 if (PyString_Check(arg)) {
6149 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006150 size_t lo = 0;
6151 size_t mid;
6152 size_t hi = tablesize;
6153 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006154 char *confname = PyString_AS_STRING(arg);
6155 while (lo < hi) {
6156 mid = (lo + hi) / 2;
6157 cmp = strcmp(confname, table[mid].name);
6158 if (cmp < 0)
6159 hi = mid;
6160 else if (cmp > 0)
6161 lo = mid + 1;
6162 else {
6163 *valuep = table[mid].value;
6164 return 1;
6165 }
6166 }
6167 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6168 }
6169 else
6170 PyErr_SetString(PyExc_TypeError,
6171 "configuration names must be strings or integers");
6172 return 0;
6173}
6174
6175
6176#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6177static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006178#ifdef _PC_ABI_AIO_XFER_MAX
6179 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6180#endif
6181#ifdef _PC_ABI_ASYNC_IO
6182 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6183#endif
Fred Drakec9680921999-12-13 16:37:25 +00006184#ifdef _PC_ASYNC_IO
6185 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6186#endif
6187#ifdef _PC_CHOWN_RESTRICTED
6188 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6189#endif
6190#ifdef _PC_FILESIZEBITS
6191 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6192#endif
6193#ifdef _PC_LAST
6194 {"PC_LAST", _PC_LAST},
6195#endif
6196#ifdef _PC_LINK_MAX
6197 {"PC_LINK_MAX", _PC_LINK_MAX},
6198#endif
6199#ifdef _PC_MAX_CANON
6200 {"PC_MAX_CANON", _PC_MAX_CANON},
6201#endif
6202#ifdef _PC_MAX_INPUT
6203 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6204#endif
6205#ifdef _PC_NAME_MAX
6206 {"PC_NAME_MAX", _PC_NAME_MAX},
6207#endif
6208#ifdef _PC_NO_TRUNC
6209 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6210#endif
6211#ifdef _PC_PATH_MAX
6212 {"PC_PATH_MAX", _PC_PATH_MAX},
6213#endif
6214#ifdef _PC_PIPE_BUF
6215 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6216#endif
6217#ifdef _PC_PRIO_IO
6218 {"PC_PRIO_IO", _PC_PRIO_IO},
6219#endif
6220#ifdef _PC_SOCK_MAXBUF
6221 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6222#endif
6223#ifdef _PC_SYNC_IO
6224 {"PC_SYNC_IO", _PC_SYNC_IO},
6225#endif
6226#ifdef _PC_VDISABLE
6227 {"PC_VDISABLE", _PC_VDISABLE},
6228#endif
6229};
6230
Fred Drakec9680921999-12-13 16:37:25 +00006231static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006232conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006233{
6234 return conv_confname(arg, valuep, posix_constants_pathconf,
6235 sizeof(posix_constants_pathconf)
6236 / sizeof(struct constdef));
6237}
6238#endif
6239
6240#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006241PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006242"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006243Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006245
6246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006247posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006248{
6249 PyObject *result = NULL;
6250 int name, fd;
6251
Fred Drake12c6e2d1999-12-14 21:25:03 +00006252 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6253 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006254 long limit;
6255
6256 errno = 0;
6257 limit = fpathconf(fd, name);
6258 if (limit == -1 && errno != 0)
6259 posix_error();
6260 else
6261 result = PyInt_FromLong(limit);
6262 }
6263 return result;
6264}
6265#endif
6266
6267
6268#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006269PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006270"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006271Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006273
6274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006275posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006276{
6277 PyObject *result = NULL;
6278 int name;
6279 char *path;
6280
6281 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6282 conv_path_confname, &name)) {
6283 long limit;
6284
6285 errno = 0;
6286 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006287 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006288 if (errno == EINVAL)
6289 /* could be a path or name problem */
6290 posix_error();
6291 else
6292 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006293 }
Fred Drakec9680921999-12-13 16:37:25 +00006294 else
6295 result = PyInt_FromLong(limit);
6296 }
6297 return result;
6298}
6299#endif
6300
6301#ifdef HAVE_CONFSTR
6302static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006303#ifdef _CS_ARCHITECTURE
6304 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6305#endif
6306#ifdef _CS_HOSTNAME
6307 {"CS_HOSTNAME", _CS_HOSTNAME},
6308#endif
6309#ifdef _CS_HW_PROVIDER
6310 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6311#endif
6312#ifdef _CS_HW_SERIAL
6313 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6314#endif
6315#ifdef _CS_INITTAB_NAME
6316 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6317#endif
Fred Drakec9680921999-12-13 16:37:25 +00006318#ifdef _CS_LFS64_CFLAGS
6319 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6320#endif
6321#ifdef _CS_LFS64_LDFLAGS
6322 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6323#endif
6324#ifdef _CS_LFS64_LIBS
6325 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6326#endif
6327#ifdef _CS_LFS64_LINTFLAGS
6328 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6329#endif
6330#ifdef _CS_LFS_CFLAGS
6331 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6332#endif
6333#ifdef _CS_LFS_LDFLAGS
6334 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6335#endif
6336#ifdef _CS_LFS_LIBS
6337 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6338#endif
6339#ifdef _CS_LFS_LINTFLAGS
6340 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6341#endif
Fred Draked86ed291999-12-15 15:34:33 +00006342#ifdef _CS_MACHINE
6343 {"CS_MACHINE", _CS_MACHINE},
6344#endif
Fred Drakec9680921999-12-13 16:37:25 +00006345#ifdef _CS_PATH
6346 {"CS_PATH", _CS_PATH},
6347#endif
Fred Draked86ed291999-12-15 15:34:33 +00006348#ifdef _CS_RELEASE
6349 {"CS_RELEASE", _CS_RELEASE},
6350#endif
6351#ifdef _CS_SRPC_DOMAIN
6352 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6353#endif
6354#ifdef _CS_SYSNAME
6355 {"CS_SYSNAME", _CS_SYSNAME},
6356#endif
6357#ifdef _CS_VERSION
6358 {"CS_VERSION", _CS_VERSION},
6359#endif
Fred Drakec9680921999-12-13 16:37:25 +00006360#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6361 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6362#endif
6363#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6364 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6365#endif
6366#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6367 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6368#endif
6369#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6370 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6371#endif
6372#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6373 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6374#endif
6375#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6376 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6377#endif
6378#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6379 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6380#endif
6381#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6382 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6383#endif
6384#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6385 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6386#endif
6387#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6388 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6389#endif
6390#ifdef _CS_XBS5_LP64_OFF64_LIBS
6391 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6392#endif
6393#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6394 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6395#endif
6396#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6397 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6398#endif
6399#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6400 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6401#endif
6402#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6403 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6404#endif
6405#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6406 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6407#endif
Fred Draked86ed291999-12-15 15:34:33 +00006408#ifdef _MIPS_CS_AVAIL_PROCESSORS
6409 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6410#endif
6411#ifdef _MIPS_CS_BASE
6412 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6413#endif
6414#ifdef _MIPS_CS_HOSTID
6415 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6416#endif
6417#ifdef _MIPS_CS_HW_NAME
6418 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6419#endif
6420#ifdef _MIPS_CS_NUM_PROCESSORS
6421 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6422#endif
6423#ifdef _MIPS_CS_OSREL_MAJ
6424 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6425#endif
6426#ifdef _MIPS_CS_OSREL_MIN
6427 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6428#endif
6429#ifdef _MIPS_CS_OSREL_PATCH
6430 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6431#endif
6432#ifdef _MIPS_CS_OS_NAME
6433 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6434#endif
6435#ifdef _MIPS_CS_OS_PROVIDER
6436 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6437#endif
6438#ifdef _MIPS_CS_PROCESSORS
6439 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6440#endif
6441#ifdef _MIPS_CS_SERIAL
6442 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6443#endif
6444#ifdef _MIPS_CS_VENDOR
6445 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6446#endif
Fred Drakec9680921999-12-13 16:37:25 +00006447};
6448
6449static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006450conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006451{
6452 return conv_confname(arg, valuep, posix_constants_confstr,
6453 sizeof(posix_constants_confstr)
6454 / sizeof(struct constdef));
6455}
6456
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006458"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006460
6461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006462posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006463{
6464 PyObject *result = NULL;
6465 int name;
6466 char buffer[64];
6467
6468 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6469 int len = confstr(name, buffer, sizeof(buffer));
6470
Fred Drakec9680921999-12-13 16:37:25 +00006471 errno = 0;
6472 if (len == 0) {
6473 if (errno != 0)
6474 posix_error();
6475 else
6476 result = PyString_FromString("");
6477 }
6478 else {
6479 if (len >= sizeof(buffer)) {
6480 result = PyString_FromStringAndSize(NULL, len);
6481 if (result != NULL)
6482 confstr(name, PyString_AS_STRING(result), len+1);
6483 }
6484 else
6485 result = PyString_FromString(buffer);
6486 }
6487 }
6488 return result;
6489}
6490#endif
6491
6492
6493#ifdef HAVE_SYSCONF
6494static struct constdef posix_constants_sysconf[] = {
6495#ifdef _SC_2_CHAR_TERM
6496 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6497#endif
6498#ifdef _SC_2_C_BIND
6499 {"SC_2_C_BIND", _SC_2_C_BIND},
6500#endif
6501#ifdef _SC_2_C_DEV
6502 {"SC_2_C_DEV", _SC_2_C_DEV},
6503#endif
6504#ifdef _SC_2_C_VERSION
6505 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6506#endif
6507#ifdef _SC_2_FORT_DEV
6508 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6509#endif
6510#ifdef _SC_2_FORT_RUN
6511 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6512#endif
6513#ifdef _SC_2_LOCALEDEF
6514 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6515#endif
6516#ifdef _SC_2_SW_DEV
6517 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6518#endif
6519#ifdef _SC_2_UPE
6520 {"SC_2_UPE", _SC_2_UPE},
6521#endif
6522#ifdef _SC_2_VERSION
6523 {"SC_2_VERSION", _SC_2_VERSION},
6524#endif
Fred Draked86ed291999-12-15 15:34:33 +00006525#ifdef _SC_ABI_ASYNCHRONOUS_IO
6526 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6527#endif
6528#ifdef _SC_ACL
6529 {"SC_ACL", _SC_ACL},
6530#endif
Fred Drakec9680921999-12-13 16:37:25 +00006531#ifdef _SC_AIO_LISTIO_MAX
6532 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6533#endif
Fred Drakec9680921999-12-13 16:37:25 +00006534#ifdef _SC_AIO_MAX
6535 {"SC_AIO_MAX", _SC_AIO_MAX},
6536#endif
6537#ifdef _SC_AIO_PRIO_DELTA_MAX
6538 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6539#endif
6540#ifdef _SC_ARG_MAX
6541 {"SC_ARG_MAX", _SC_ARG_MAX},
6542#endif
6543#ifdef _SC_ASYNCHRONOUS_IO
6544 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6545#endif
6546#ifdef _SC_ATEXIT_MAX
6547 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6548#endif
Fred Draked86ed291999-12-15 15:34:33 +00006549#ifdef _SC_AUDIT
6550 {"SC_AUDIT", _SC_AUDIT},
6551#endif
Fred Drakec9680921999-12-13 16:37:25 +00006552#ifdef _SC_AVPHYS_PAGES
6553 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6554#endif
6555#ifdef _SC_BC_BASE_MAX
6556 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6557#endif
6558#ifdef _SC_BC_DIM_MAX
6559 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6560#endif
6561#ifdef _SC_BC_SCALE_MAX
6562 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6563#endif
6564#ifdef _SC_BC_STRING_MAX
6565 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6566#endif
Fred Draked86ed291999-12-15 15:34:33 +00006567#ifdef _SC_CAP
6568 {"SC_CAP", _SC_CAP},
6569#endif
Fred Drakec9680921999-12-13 16:37:25 +00006570#ifdef _SC_CHARCLASS_NAME_MAX
6571 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6572#endif
6573#ifdef _SC_CHAR_BIT
6574 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6575#endif
6576#ifdef _SC_CHAR_MAX
6577 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6578#endif
6579#ifdef _SC_CHAR_MIN
6580 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6581#endif
6582#ifdef _SC_CHILD_MAX
6583 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6584#endif
6585#ifdef _SC_CLK_TCK
6586 {"SC_CLK_TCK", _SC_CLK_TCK},
6587#endif
6588#ifdef _SC_COHER_BLKSZ
6589 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6590#endif
6591#ifdef _SC_COLL_WEIGHTS_MAX
6592 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6593#endif
6594#ifdef _SC_DCACHE_ASSOC
6595 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6596#endif
6597#ifdef _SC_DCACHE_BLKSZ
6598 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6599#endif
6600#ifdef _SC_DCACHE_LINESZ
6601 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6602#endif
6603#ifdef _SC_DCACHE_SZ
6604 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6605#endif
6606#ifdef _SC_DCACHE_TBLKSZ
6607 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6608#endif
6609#ifdef _SC_DELAYTIMER_MAX
6610 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6611#endif
6612#ifdef _SC_EQUIV_CLASS_MAX
6613 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6614#endif
6615#ifdef _SC_EXPR_NEST_MAX
6616 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6617#endif
6618#ifdef _SC_FSYNC
6619 {"SC_FSYNC", _SC_FSYNC},
6620#endif
6621#ifdef _SC_GETGR_R_SIZE_MAX
6622 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6623#endif
6624#ifdef _SC_GETPW_R_SIZE_MAX
6625 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6626#endif
6627#ifdef _SC_ICACHE_ASSOC
6628 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6629#endif
6630#ifdef _SC_ICACHE_BLKSZ
6631 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6632#endif
6633#ifdef _SC_ICACHE_LINESZ
6634 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6635#endif
6636#ifdef _SC_ICACHE_SZ
6637 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6638#endif
Fred Draked86ed291999-12-15 15:34:33 +00006639#ifdef _SC_INF
6640 {"SC_INF", _SC_INF},
6641#endif
Fred Drakec9680921999-12-13 16:37:25 +00006642#ifdef _SC_INT_MAX
6643 {"SC_INT_MAX", _SC_INT_MAX},
6644#endif
6645#ifdef _SC_INT_MIN
6646 {"SC_INT_MIN", _SC_INT_MIN},
6647#endif
6648#ifdef _SC_IOV_MAX
6649 {"SC_IOV_MAX", _SC_IOV_MAX},
6650#endif
Fred Draked86ed291999-12-15 15:34:33 +00006651#ifdef _SC_IP_SECOPTS
6652 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6653#endif
Fred Drakec9680921999-12-13 16:37:25 +00006654#ifdef _SC_JOB_CONTROL
6655 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6656#endif
Fred Draked86ed291999-12-15 15:34:33 +00006657#ifdef _SC_KERN_POINTERS
6658 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6659#endif
6660#ifdef _SC_KERN_SIM
6661 {"SC_KERN_SIM", _SC_KERN_SIM},
6662#endif
Fred Drakec9680921999-12-13 16:37:25 +00006663#ifdef _SC_LINE_MAX
6664 {"SC_LINE_MAX", _SC_LINE_MAX},
6665#endif
6666#ifdef _SC_LOGIN_NAME_MAX
6667 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6668#endif
6669#ifdef _SC_LOGNAME_MAX
6670 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6671#endif
6672#ifdef _SC_LONG_BIT
6673 {"SC_LONG_BIT", _SC_LONG_BIT},
6674#endif
Fred Draked86ed291999-12-15 15:34:33 +00006675#ifdef _SC_MAC
6676 {"SC_MAC", _SC_MAC},
6677#endif
Fred Drakec9680921999-12-13 16:37:25 +00006678#ifdef _SC_MAPPED_FILES
6679 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6680#endif
6681#ifdef _SC_MAXPID
6682 {"SC_MAXPID", _SC_MAXPID},
6683#endif
6684#ifdef _SC_MB_LEN_MAX
6685 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6686#endif
6687#ifdef _SC_MEMLOCK
6688 {"SC_MEMLOCK", _SC_MEMLOCK},
6689#endif
6690#ifdef _SC_MEMLOCK_RANGE
6691 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6692#endif
6693#ifdef _SC_MEMORY_PROTECTION
6694 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6695#endif
6696#ifdef _SC_MESSAGE_PASSING
6697 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6698#endif
Fred Draked86ed291999-12-15 15:34:33 +00006699#ifdef _SC_MMAP_FIXED_ALIGNMENT
6700 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6701#endif
Fred Drakec9680921999-12-13 16:37:25 +00006702#ifdef _SC_MQ_OPEN_MAX
6703 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6704#endif
6705#ifdef _SC_MQ_PRIO_MAX
6706 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6707#endif
Fred Draked86ed291999-12-15 15:34:33 +00006708#ifdef _SC_NACLS_MAX
6709 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6710#endif
Fred Drakec9680921999-12-13 16:37:25 +00006711#ifdef _SC_NGROUPS_MAX
6712 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6713#endif
6714#ifdef _SC_NL_ARGMAX
6715 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6716#endif
6717#ifdef _SC_NL_LANGMAX
6718 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6719#endif
6720#ifdef _SC_NL_MSGMAX
6721 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6722#endif
6723#ifdef _SC_NL_NMAX
6724 {"SC_NL_NMAX", _SC_NL_NMAX},
6725#endif
6726#ifdef _SC_NL_SETMAX
6727 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6728#endif
6729#ifdef _SC_NL_TEXTMAX
6730 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6731#endif
6732#ifdef _SC_NPROCESSORS_CONF
6733 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6734#endif
6735#ifdef _SC_NPROCESSORS_ONLN
6736 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6737#endif
Fred Draked86ed291999-12-15 15:34:33 +00006738#ifdef _SC_NPROC_CONF
6739 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6740#endif
6741#ifdef _SC_NPROC_ONLN
6742 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6743#endif
Fred Drakec9680921999-12-13 16:37:25 +00006744#ifdef _SC_NZERO
6745 {"SC_NZERO", _SC_NZERO},
6746#endif
6747#ifdef _SC_OPEN_MAX
6748 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6749#endif
6750#ifdef _SC_PAGESIZE
6751 {"SC_PAGESIZE", _SC_PAGESIZE},
6752#endif
6753#ifdef _SC_PAGE_SIZE
6754 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6755#endif
6756#ifdef _SC_PASS_MAX
6757 {"SC_PASS_MAX", _SC_PASS_MAX},
6758#endif
6759#ifdef _SC_PHYS_PAGES
6760 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6761#endif
6762#ifdef _SC_PII
6763 {"SC_PII", _SC_PII},
6764#endif
6765#ifdef _SC_PII_INTERNET
6766 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6767#endif
6768#ifdef _SC_PII_INTERNET_DGRAM
6769 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6770#endif
6771#ifdef _SC_PII_INTERNET_STREAM
6772 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6773#endif
6774#ifdef _SC_PII_OSI
6775 {"SC_PII_OSI", _SC_PII_OSI},
6776#endif
6777#ifdef _SC_PII_OSI_CLTS
6778 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6779#endif
6780#ifdef _SC_PII_OSI_COTS
6781 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6782#endif
6783#ifdef _SC_PII_OSI_M
6784 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6785#endif
6786#ifdef _SC_PII_SOCKET
6787 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6788#endif
6789#ifdef _SC_PII_XTI
6790 {"SC_PII_XTI", _SC_PII_XTI},
6791#endif
6792#ifdef _SC_POLL
6793 {"SC_POLL", _SC_POLL},
6794#endif
6795#ifdef _SC_PRIORITIZED_IO
6796 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6797#endif
6798#ifdef _SC_PRIORITY_SCHEDULING
6799 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6800#endif
6801#ifdef _SC_REALTIME_SIGNALS
6802 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6803#endif
6804#ifdef _SC_RE_DUP_MAX
6805 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6806#endif
6807#ifdef _SC_RTSIG_MAX
6808 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6809#endif
6810#ifdef _SC_SAVED_IDS
6811 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6812#endif
6813#ifdef _SC_SCHAR_MAX
6814 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6815#endif
6816#ifdef _SC_SCHAR_MIN
6817 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6818#endif
6819#ifdef _SC_SELECT
6820 {"SC_SELECT", _SC_SELECT},
6821#endif
6822#ifdef _SC_SEMAPHORES
6823 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6824#endif
6825#ifdef _SC_SEM_NSEMS_MAX
6826 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6827#endif
6828#ifdef _SC_SEM_VALUE_MAX
6829 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6830#endif
6831#ifdef _SC_SHARED_MEMORY_OBJECTS
6832 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6833#endif
6834#ifdef _SC_SHRT_MAX
6835 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6836#endif
6837#ifdef _SC_SHRT_MIN
6838 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6839#endif
6840#ifdef _SC_SIGQUEUE_MAX
6841 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6842#endif
6843#ifdef _SC_SIGRT_MAX
6844 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6845#endif
6846#ifdef _SC_SIGRT_MIN
6847 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6848#endif
Fred Draked86ed291999-12-15 15:34:33 +00006849#ifdef _SC_SOFTPOWER
6850 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6851#endif
Fred Drakec9680921999-12-13 16:37:25 +00006852#ifdef _SC_SPLIT_CACHE
6853 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6854#endif
6855#ifdef _SC_SSIZE_MAX
6856 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6857#endif
6858#ifdef _SC_STACK_PROT
6859 {"SC_STACK_PROT", _SC_STACK_PROT},
6860#endif
6861#ifdef _SC_STREAM_MAX
6862 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6863#endif
6864#ifdef _SC_SYNCHRONIZED_IO
6865 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6866#endif
6867#ifdef _SC_THREADS
6868 {"SC_THREADS", _SC_THREADS},
6869#endif
6870#ifdef _SC_THREAD_ATTR_STACKADDR
6871 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6872#endif
6873#ifdef _SC_THREAD_ATTR_STACKSIZE
6874 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6875#endif
6876#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6877 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6878#endif
6879#ifdef _SC_THREAD_KEYS_MAX
6880 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6881#endif
6882#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6883 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6884#endif
6885#ifdef _SC_THREAD_PRIO_INHERIT
6886 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6887#endif
6888#ifdef _SC_THREAD_PRIO_PROTECT
6889 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6890#endif
6891#ifdef _SC_THREAD_PROCESS_SHARED
6892 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6893#endif
6894#ifdef _SC_THREAD_SAFE_FUNCTIONS
6895 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6896#endif
6897#ifdef _SC_THREAD_STACK_MIN
6898 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6899#endif
6900#ifdef _SC_THREAD_THREADS_MAX
6901 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6902#endif
6903#ifdef _SC_TIMERS
6904 {"SC_TIMERS", _SC_TIMERS},
6905#endif
6906#ifdef _SC_TIMER_MAX
6907 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6908#endif
6909#ifdef _SC_TTY_NAME_MAX
6910 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6911#endif
6912#ifdef _SC_TZNAME_MAX
6913 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6914#endif
6915#ifdef _SC_T_IOV_MAX
6916 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6917#endif
6918#ifdef _SC_UCHAR_MAX
6919 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6920#endif
6921#ifdef _SC_UINT_MAX
6922 {"SC_UINT_MAX", _SC_UINT_MAX},
6923#endif
6924#ifdef _SC_UIO_MAXIOV
6925 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6926#endif
6927#ifdef _SC_ULONG_MAX
6928 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6929#endif
6930#ifdef _SC_USHRT_MAX
6931 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6932#endif
6933#ifdef _SC_VERSION
6934 {"SC_VERSION", _SC_VERSION},
6935#endif
6936#ifdef _SC_WORD_BIT
6937 {"SC_WORD_BIT", _SC_WORD_BIT},
6938#endif
6939#ifdef _SC_XBS5_ILP32_OFF32
6940 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6941#endif
6942#ifdef _SC_XBS5_ILP32_OFFBIG
6943 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6944#endif
6945#ifdef _SC_XBS5_LP64_OFF64
6946 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6947#endif
6948#ifdef _SC_XBS5_LPBIG_OFFBIG
6949 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6950#endif
6951#ifdef _SC_XOPEN_CRYPT
6952 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6953#endif
6954#ifdef _SC_XOPEN_ENH_I18N
6955 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6956#endif
6957#ifdef _SC_XOPEN_LEGACY
6958 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6959#endif
6960#ifdef _SC_XOPEN_REALTIME
6961 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6962#endif
6963#ifdef _SC_XOPEN_REALTIME_THREADS
6964 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6965#endif
6966#ifdef _SC_XOPEN_SHM
6967 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6968#endif
6969#ifdef _SC_XOPEN_UNIX
6970 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6971#endif
6972#ifdef _SC_XOPEN_VERSION
6973 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6974#endif
6975#ifdef _SC_XOPEN_XCU_VERSION
6976 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6977#endif
6978#ifdef _SC_XOPEN_XPG2
6979 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6980#endif
6981#ifdef _SC_XOPEN_XPG3
6982 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6983#endif
6984#ifdef _SC_XOPEN_XPG4
6985 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6986#endif
6987};
6988
6989static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006990conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006991{
6992 return conv_confname(arg, valuep, posix_constants_sysconf,
6993 sizeof(posix_constants_sysconf)
6994 / sizeof(struct constdef));
6995}
6996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006997PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006998"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006999Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007000
7001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007002posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007003{
7004 PyObject *result = NULL;
7005 int name;
7006
7007 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7008 int value;
7009
7010 errno = 0;
7011 value = sysconf(name);
7012 if (value == -1 && errno != 0)
7013 posix_error();
7014 else
7015 result = PyInt_FromLong(value);
7016 }
7017 return result;
7018}
7019#endif
7020
7021
Fred Drakebec628d1999-12-15 18:31:10 +00007022/* This code is used to ensure that the tables of configuration value names
7023 * are in sorted order as required by conv_confname(), and also to build the
7024 * the exported dictionaries that are used to publish information about the
7025 * names available on the host platform.
7026 *
7027 * Sorting the table at runtime ensures that the table is properly ordered
7028 * when used, even for platforms we're not able to test on. It also makes
7029 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007030 */
Fred Drakebec628d1999-12-15 18:31:10 +00007031
7032static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007033cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007034{
7035 const struct constdef *c1 =
7036 (const struct constdef *) v1;
7037 const struct constdef *c2 =
7038 (const struct constdef *) v2;
7039
7040 return strcmp(c1->name, c2->name);
7041}
7042
7043static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007044setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007045 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007046{
Fred Drakebec628d1999-12-15 18:31:10 +00007047 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007048 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007049
7050 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7051 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007052 if (d == NULL)
7053 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007054
Barry Warsaw3155db32000-04-13 15:20:40 +00007055 for (i=0; i < tablesize; ++i) {
7056 PyObject *o = PyInt_FromLong(table[i].value);
7057 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7058 Py_XDECREF(o);
7059 Py_DECREF(d);
7060 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007061 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007062 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007063 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007064 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007065}
7066
Fred Drakebec628d1999-12-15 18:31:10 +00007067/* Return -1 on failure, 0 on success. */
7068static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007069setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007070{
7071#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007072 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007073 sizeof(posix_constants_pathconf)
7074 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007075 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007076 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007077#endif
7078#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007079 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007080 sizeof(posix_constants_confstr)
7081 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007082 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007083 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007084#endif
7085#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007086 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007087 sizeof(posix_constants_sysconf)
7088 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007089 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007090 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007091#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007092 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007093}
Fred Draked86ed291999-12-15 15:34:33 +00007094
7095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007096PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007097"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007099in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007100
7101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007102posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007103{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007104 abort();
7105 /*NOTREACHED*/
7106 Py_FatalError("abort() called from Python code didn't abort!");
7107 return NULL;
7108}
Fred Drakebec628d1999-12-15 18:31:10 +00007109
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007110#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007111PyDoc_STRVAR(win32_startfile__doc__,
7112"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007113\n\
7114This acts like double-clicking the file in Explorer, or giving the file\n\
7115name as an argument to the DOS \"start\" command: the file is opened\n\
7116with whatever application (if any) its extension is associated.\n\
7117\n\
7118startfile returns as soon as the associated application is launched.\n\
7119There is no option to wait for the application to close, and no way\n\
7120to retrieve the application's exit status.\n\
7121\n\
7122The filepath is relative to the current directory. If you want to use\n\
7123an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007124the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007125
7126static PyObject *
7127win32_startfile(PyObject *self, PyObject *args)
7128{
7129 char *filepath;
7130 HINSTANCE rc;
7131 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7132 return NULL;
7133 Py_BEGIN_ALLOW_THREADS
7134 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7135 Py_END_ALLOW_THREADS
7136 if (rc <= (HINSTANCE)32)
7137 return win32_error("startfile", filepath);
7138 Py_INCREF(Py_None);
7139 return Py_None;
7140}
7141#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007142
Martin v. Löwis438b5342002-12-27 10:16:42 +00007143#ifdef HAVE_GETLOADAVG
7144PyDoc_STRVAR(posix_getloadavg__doc__,
7145"getloadavg() -> (float, float, float)\n\n\
7146Return the number of processes in the system run queue averaged over\n\
7147the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7148was unobtainable");
7149
7150static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007151posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007152{
7153 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007154 if (getloadavg(loadavg, 3)!=3) {
7155 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7156 return NULL;
7157 } else
7158 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7159}
7160#endif
7161
7162
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007163static PyMethodDef posix_methods[] = {
7164 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7165#ifdef HAVE_TTYNAME
7166 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7167#endif
7168 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7169 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007170#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007172#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007173#ifdef HAVE_LCHOWN
7174 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7175#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007176#ifdef HAVE_CHROOT
7177 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7178#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007180 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007181#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007182#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007183 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007184#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007185 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007186#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007187#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007188#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007189 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007190#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007191 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7192 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7193 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007194#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007195 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007196#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007197#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007199#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7201 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7202 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007203 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007204#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007205 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007206#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007207#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007208 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007209#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007210 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007211#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007212 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007213#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007214 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7215 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7216 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007217#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007218 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007219#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007220 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007221#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007222 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7223 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007224#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007225#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007226 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7227 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007228#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007229#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007230 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007231#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007232#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007233 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007234#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007235#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007236 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007237#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007238#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007239 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007240#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007241#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007242 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007243#endif /* HAVE_GETEGID */
7244#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007245 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007246#endif /* HAVE_GETEUID */
7247#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007248 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007249#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007250#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007251 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007252#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007253 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007254#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007255 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007256#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007257#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007258 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007259#endif /* HAVE_GETPPID */
7260#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007261 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007262#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007263#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007264 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007265#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007266#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007267 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007268#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007269#ifdef HAVE_KILLPG
7270 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7271#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007272#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007273 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007274#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007275#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007276 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007277#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007278 {"popen2", win32_popen2, METH_VARARGS},
7279 {"popen3", win32_popen3, METH_VARARGS},
7280 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007281 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007282#else
7283#if defined(PYOS_OS2) && defined(PYCC_GCC)
7284 {"popen2", os2emx_popen2, METH_VARARGS},
7285 {"popen3", os2emx_popen3, METH_VARARGS},
7286 {"popen4", os2emx_popen4, METH_VARARGS},
7287#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007288#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007289#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007290#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007291 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007292#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007293#ifdef HAVE_SETEUID
7294 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7295#endif /* HAVE_SETEUID */
7296#ifdef HAVE_SETEGID
7297 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7298#endif /* HAVE_SETEGID */
7299#ifdef HAVE_SETREUID
7300 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7301#endif /* HAVE_SETREUID */
7302#ifdef HAVE_SETREGID
7303 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7304#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007305#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007306 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007307#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007308#ifdef HAVE_SETGROUPS
7309 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7310#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007311#ifdef HAVE_GETPGID
7312 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7313#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007314#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007315 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007316#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007317#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007318 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007319#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007320#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007321 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007322#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007323#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007324 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007325#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007326#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007327 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007328#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007329#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007330 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007331#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007332#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007333 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007334#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007335 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7336 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7337 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7338 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7339 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7340 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7341 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7342 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7343 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007344 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007345#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007346 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007347#endif
7348#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007349 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007350#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007351#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007352 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7353#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007354#ifdef HAVE_DEVICE_MACROS
7355 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7356 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7357 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7358#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007359#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007360 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007361#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007362#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007363 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007364#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007365#ifdef HAVE_UNSETENV
7366 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7367#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007368#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007369 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007370#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007371#ifdef HAVE_FCHDIR
7372 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7373#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007374#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007375 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007376#endif
7377#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007378 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007379#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007380#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007381#ifdef WCOREDUMP
7382 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7383#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007384#ifdef WIFCONTINUED
7385 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7386#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007387#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007388 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007389#endif /* WIFSTOPPED */
7390#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007391 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007392#endif /* WIFSIGNALED */
7393#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007395#endif /* WIFEXITED */
7396#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007397 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007398#endif /* WEXITSTATUS */
7399#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007400 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007401#endif /* WTERMSIG */
7402#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007403 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007404#endif /* WSTOPSIG */
7405#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007406#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007407 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007408#endif
7409#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007410 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007411#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007412#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007413 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007414#endif
7415#ifdef HAVE_TEMPNAM
7416 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7417#endif
7418#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007419 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007420#endif
Fred Drakec9680921999-12-13 16:37:25 +00007421#ifdef HAVE_CONFSTR
7422 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7423#endif
7424#ifdef HAVE_SYSCONF
7425 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7426#endif
7427#ifdef HAVE_FPATHCONF
7428 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7429#endif
7430#ifdef HAVE_PATHCONF
7431 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7432#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007433 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007434#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007435 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7436#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007437#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007438 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007439#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007440 {NULL, NULL} /* Sentinel */
7441};
7442
7443
Barry Warsaw4a342091996-12-19 23:50:02 +00007444static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007445ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007446{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007447 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007448}
7449
Guido van Rossumd48f2521997-12-05 22:19:34 +00007450#if defined(PYOS_OS2)
7451/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007452static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007453{
7454 APIRET rc;
7455 ULONG values[QSV_MAX+1];
7456 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007457 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007458
7459 Py_BEGIN_ALLOW_THREADS
7460 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7461 Py_END_ALLOW_THREADS
7462
7463 if (rc != NO_ERROR) {
7464 os2_error(rc);
7465 return -1;
7466 }
7467
Fred Drake4d1e64b2002-04-15 19:40:07 +00007468 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7469 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7470 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7471 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7472 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7473 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7474 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007475
7476 switch (values[QSV_VERSION_MINOR]) {
7477 case 0: ver = "2.00"; break;
7478 case 10: ver = "2.10"; break;
7479 case 11: ver = "2.11"; break;
7480 case 30: ver = "3.00"; break;
7481 case 40: ver = "4.00"; break;
7482 case 50: ver = "5.00"; break;
7483 default:
Tim Peters885d4572001-11-28 20:27:42 +00007484 PyOS_snprintf(tmp, sizeof(tmp),
7485 "%d-%d", values[QSV_VERSION_MAJOR],
7486 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007487 ver = &tmp[0];
7488 }
7489
7490 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007491 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007492 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007493
7494 /* Add Indicator of Which Drive was Used to Boot the System */
7495 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7496 tmp[1] = ':';
7497 tmp[2] = '\0';
7498
Fred Drake4d1e64b2002-04-15 19:40:07 +00007499 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007500}
7501#endif
7502
Barry Warsaw4a342091996-12-19 23:50:02 +00007503static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007504all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007505{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007506#ifdef F_OK
7507 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007508#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007509#ifdef R_OK
7510 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007511#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007512#ifdef W_OK
7513 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007514#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007515#ifdef X_OK
7516 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007517#endif
Fred Drakec9680921999-12-13 16:37:25 +00007518#ifdef NGROUPS_MAX
7519 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7520#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007521#ifdef TMP_MAX
7522 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7523#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007524#ifdef WCONTINUED
7525 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7526#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007527#ifdef WNOHANG
7528 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007529#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007530#ifdef WUNTRACED
7531 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7532#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007533#ifdef O_RDONLY
7534 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7535#endif
7536#ifdef O_WRONLY
7537 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7538#endif
7539#ifdef O_RDWR
7540 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7541#endif
7542#ifdef O_NDELAY
7543 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7544#endif
7545#ifdef O_NONBLOCK
7546 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7547#endif
7548#ifdef O_APPEND
7549 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7550#endif
7551#ifdef O_DSYNC
7552 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7553#endif
7554#ifdef O_RSYNC
7555 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7556#endif
7557#ifdef O_SYNC
7558 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7559#endif
7560#ifdef O_NOCTTY
7561 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7562#endif
7563#ifdef O_CREAT
7564 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7565#endif
7566#ifdef O_EXCL
7567 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7568#endif
7569#ifdef O_TRUNC
7570 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7571#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007572#ifdef O_BINARY
7573 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7574#endif
7575#ifdef O_TEXT
7576 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7577#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007578#ifdef O_LARGEFILE
7579 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7580#endif
7581
Tim Peters5aa91602002-01-30 05:46:57 +00007582/* MS Windows */
7583#ifdef O_NOINHERIT
7584 /* Don't inherit in child processes. */
7585 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7586#endif
7587#ifdef _O_SHORT_LIVED
7588 /* Optimize for short life (keep in memory). */
7589 /* MS forgot to define this one with a non-underscore form too. */
7590 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7591#endif
7592#ifdef O_TEMPORARY
7593 /* Automatically delete when last handle is closed. */
7594 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7595#endif
7596#ifdef O_RANDOM
7597 /* Optimize for random access. */
7598 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7599#endif
7600#ifdef O_SEQUENTIAL
7601 /* Optimize for sequential access. */
7602 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7603#endif
7604
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007605/* GNU extensions. */
7606#ifdef O_DIRECT
7607 /* Direct disk access. */
7608 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7609#endif
7610#ifdef O_DIRECTORY
7611 /* Must be a directory. */
7612 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7613#endif
7614#ifdef O_NOFOLLOW
7615 /* Do not follow links. */
7616 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7617#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007618
Barry Warsaw5676bd12003-01-07 20:57:09 +00007619 /* These come from sysexits.h */
7620#ifdef EX_OK
7621 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007622#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007623#ifdef EX_USAGE
7624 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007625#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007626#ifdef EX_DATAERR
7627 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007628#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007629#ifdef EX_NOINPUT
7630 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007631#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007632#ifdef EX_NOUSER
7633 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007634#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007635#ifdef EX_NOHOST
7636 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007637#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007638#ifdef EX_UNAVAILABLE
7639 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007640#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007641#ifdef EX_SOFTWARE
7642 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007643#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007644#ifdef EX_OSERR
7645 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007646#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007647#ifdef EX_OSFILE
7648 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007649#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007650#ifdef EX_CANTCREAT
7651 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007652#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007653#ifdef EX_IOERR
7654 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007655#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007656#ifdef EX_TEMPFAIL
7657 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007658#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007659#ifdef EX_PROTOCOL
7660 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007661#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007662#ifdef EX_NOPERM
7663 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007664#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007665#ifdef EX_CONFIG
7666 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007667#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007668#ifdef EX_NOTFOUND
7669 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007670#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007671
Guido van Rossum246bc171999-02-01 23:54:31 +00007672#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007673#if defined(PYOS_OS2) && defined(PYCC_GCC)
7674 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7675 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7676 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7677 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7678 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7679 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7680 if (ins(d, "P_PM", (long)P_PM)) return -1;
7681 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7682 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7683 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7684 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7685 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7686 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7687 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7688 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7689 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7690 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7691 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7692 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7693 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7694#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007695 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7696 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7697 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7698 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7699 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007700#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007701#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007702
Guido van Rossumd48f2521997-12-05 22:19:34 +00007703#if defined(PYOS_OS2)
7704 if (insertvalues(d)) return -1;
7705#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007706 return 0;
7707}
7708
7709
Tim Peters5aa91602002-01-30 05:46:57 +00007710#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007711#define INITFUNC initnt
7712#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007713
7714#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007715#define INITFUNC initos2
7716#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007717
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007718#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007719#define INITFUNC initposix
7720#define MODNAME "posix"
7721#endif
7722
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007723PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007724INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007725{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007726 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007727
Fred Drake4d1e64b2002-04-15 19:40:07 +00007728 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007729 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007730 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007731
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007732 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007733 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007734 Py_XINCREF(v);
7735 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007736 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007737 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007738
Fred Drake4d1e64b2002-04-15 19:40:07 +00007739 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007740 return;
7741
Fred Drake4d1e64b2002-04-15 19:40:07 +00007742 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007743 return;
7744
Fred Drake4d1e64b2002-04-15 19:40:07 +00007745 Py_INCREF(PyExc_OSError);
7746 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007747
Guido van Rossumb3d39562000-01-31 18:41:26 +00007748#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007749 if (posix_putenv_garbage == NULL)
7750 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007751#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007752
Guido van Rossum14648392001-12-08 18:02:58 +00007753 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007754 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7755 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7756 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007757 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007758 structseq_new = StatResultType.tp_new;
7759 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007760 Py_INCREF((PyObject*) &StatResultType);
7761 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007762
Guido van Rossum14648392001-12-08 18:02:58 +00007763 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007764 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007765 Py_INCREF((PyObject*) &StatVFSResultType);
7766 PyModule_AddObject(m, "statvfs_result",
7767 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007768}