blob: d203378d3dfaeae22087226ab072fd803c7a8ef8 [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
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001774 char *name;
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;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001778 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001780 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001781 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001782 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001783 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001784 closedir(dirp);
1785 return NULL;
1786 }
1787 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001788 if (ep->d_name[0] == '.' &&
1789 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001790 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001791 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001793 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001794 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001795 d = NULL;
1796 break;
1797 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001798 if (PyList_Append(d, v) != 0) {
1799 Py_DECREF(v);
1800 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001801 d = NULL;
1802 break;
1803 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001804 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001805 }
1806 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001807
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001808 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001809
Tim Peters0bb44a42000-09-15 07:44:49 +00001810#endif /* which OS */
1811} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001812
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001813#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001814/* A helper function for abspath on win32 */
1815static PyObject *
1816posix__getfullpathname(PyObject *self, PyObject *args)
1817{
1818 /* assume encoded strings wont more than double no of chars */
1819 char inbuf[MAX_PATH*2];
1820 char *inbufp = inbuf;
1821 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1822 char outbuf[MAX_PATH*2];
1823 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001824#ifdef Py_WIN_WIDE_FILENAMES
1825 if (unicode_file_names()) {
1826 PyUnicodeObject *po;
1827 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1828 Py_UNICODE woutbuf[MAX_PATH*2];
1829 Py_UNICODE *wtemp;
1830 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1831 sizeof(woutbuf)/sizeof(woutbuf[0]),
1832 woutbuf, &wtemp))
1833 return win32_error("GetFullPathName", "");
1834 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1835 }
1836 /* Drop the argument parsing error as narrow strings
1837 are also valid. */
1838 PyErr_Clear();
1839 }
1840#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001841 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1842 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001843 &insize))
1844 return NULL;
1845 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1846 outbuf, &temp))
1847 return win32_error("GetFullPathName", inbuf);
1848 return PyString_FromString(outbuf);
1849} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001850#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001853"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855
Barry Warsaw53699e91996-12-10 23:23:01 +00001856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001857posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001858{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001859 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001860 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001861 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001862
1863#ifdef Py_WIN_WIDE_FILENAMES
1864 if (unicode_file_names()) {
1865 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001866 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001867 Py_BEGIN_ALLOW_THREADS
1868 /* PyUnicode_AS_UNICODE OK without thread lock as
1869 it is a simple dereference. */
1870 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1871 Py_END_ALLOW_THREADS
1872 if (res < 0)
1873 return posix_error();
1874 Py_INCREF(Py_None);
1875 return Py_None;
1876 }
1877 /* Drop the argument parsing error as narrow strings
1878 are also valid. */
1879 PyErr_Clear();
1880 }
1881#endif
1882
Tim Peters5aa91602002-01-30 05:46:57 +00001883 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001884 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001887#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001888 res = mkdir(path);
1889#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001890 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001891#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001893 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001894 return posix_error_with_allocated_filename(path);
1895 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001896 Py_INCREF(Py_None);
1897 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001898}
1899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001900
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001902#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1903#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1904#include <sys/resource.h>
1905#endif
1906#endif
1907
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001908PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001909"nice(inc) -> new_priority\n\n\
1910Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001911
Barry Warsaw53699e91996-12-10 23:23:01 +00001912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001913posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001914{
1915 int increment, value;
1916
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001917 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001918 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001919
1920 /* There are two flavours of 'nice': one that returns the new
1921 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001922 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1923 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001924
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001925 If we are of the nice family that returns the new priority, we
1926 need to clear errno before the call, and check if errno is filled
1927 before calling posix_error() on a returnvalue of -1, because the
1928 -1 may be the actual new priority! */
1929
1930 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001931 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001932#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001933 if (value == 0)
1934 value = getpriority(PRIO_PROCESS, 0);
1935#endif
1936 if (value == -1 && errno != 0)
1937 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001938 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001939 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001940}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001941#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001944PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001945"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001946Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001947
Barry Warsaw53699e91996-12-10 23:23:01 +00001948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001949posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001950{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001951#ifdef MS_WINDOWS
1952 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1953#else
1954 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1955#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001956}
1957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001959PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001960"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001962
Barry Warsaw53699e91996-12-10 23:23:01 +00001963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001964posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001965{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001966#ifdef MS_WINDOWS
1967 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1968#else
1969 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1970#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001971}
1972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001973
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001975"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001976Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001977
Barry Warsaw53699e91996-12-10 23:23:01 +00001978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001979posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001980{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001981#ifdef MS_WINDOWS
1982 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1983#else
1984 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1985#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
1987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001988
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001989#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001990PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001991"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993
Barry Warsaw53699e91996-12-10 23:23:01 +00001994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001995posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001996{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001997 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001998 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001999 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002000 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002001 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002002 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002003 Py_END_ALLOW_THREADS
2004 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002005}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002006#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002009PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002010"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002012
Barry Warsaw53699e91996-12-10 23:23:01 +00002013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002014posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002015{
2016 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002017 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002019 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002020 if (i < 0)
2021 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002022 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002023}
2024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002025
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002027"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002030PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002031"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002033
Barry Warsaw53699e91996-12-10 23:23:01 +00002034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002035posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002036{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002037#ifdef MS_WINDOWS
2038 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2039#else
2040 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2041#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042}
2043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
Guido van Rossumb6775db1994-08-01 11:34:53 +00002045#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002047"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Barry Warsaw53699e91996-12-10 23:23:01 +00002050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002051posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002052{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002053 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002054 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002055
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002057 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002059 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002060 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002061 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002062 u.sysname,
2063 u.nodename,
2064 u.release,
2065 u.version,
2066 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002067}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002068#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002069
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002070static int
2071extract_time(PyObject *t, long* sec, long* usec)
2072{
2073 long intval;
2074 if (PyFloat_Check(t)) {
2075 double tval = PyFloat_AsDouble(t);
2076 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2077 if (!intobj)
2078 return -1;
2079 intval = PyInt_AsLong(intobj);
2080 Py_DECREF(intobj);
2081 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002082 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002083 if (*usec < 0)
2084 /* If rounding gave us a negative number,
2085 truncate. */
2086 *usec = 0;
2087 return 0;
2088 }
2089 intval = PyInt_AsLong(t);
2090 if (intval == -1 && PyErr_Occurred())
2091 return -1;
2092 *sec = intval;
2093 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002094 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002095}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002097PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002098"utime(path, (atime, utime))\n\
2099utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002100Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002101second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002102
Barry Warsaw53699e91996-12-10 23:23:01 +00002103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002104posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002106 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002107 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002108 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002109 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002110
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002111#if defined(HAVE_UTIMES)
2112 struct timeval buf[2];
2113#define ATIME buf[0].tv_sec
2114#define MTIME buf[1].tv_sec
2115#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002116/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002117 struct utimbuf buf;
2118#define ATIME buf.actime
2119#define MTIME buf.modtime
2120#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002121#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002122 time_t buf[2];
2123#define ATIME buf[0]
2124#define MTIME buf[1]
2125#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002126#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002127
Barry Warsaw3cef8562000-05-01 16:17:24 +00002128 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002129 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002130 if (arg == Py_None) {
2131 /* optional time values not given */
2132 Py_BEGIN_ALLOW_THREADS
2133 res = utime(path, NULL);
2134 Py_END_ALLOW_THREADS
2135 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002136 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002137 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002138 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002139 return NULL;
2140 }
2141 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002142 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2143 &atime, &ausec) == -1)
2144 return NULL;
2145 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2146 &mtime, &musec) == -1)
2147 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002148 ATIME = atime;
2149 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002150#ifdef HAVE_UTIMES
2151 buf[0].tv_usec = ausec;
2152 buf[1].tv_usec = musec;
2153 Py_BEGIN_ALLOW_THREADS
2154 res = utimes(path, buf);
2155 Py_END_ALLOW_THREADS
2156#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002157 Py_BEGIN_ALLOW_THREADS
2158 res = utime(path, UTIME_ARG);
2159 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002160#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002161 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002162 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002163 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002164 Py_INCREF(Py_None);
2165 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002166#undef UTIME_ARG
2167#undef ATIME
2168#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002169}
2170
Guido van Rossum85e3b011991-06-03 12:42:10 +00002171
Guido van Rossum3b066191991-06-04 19:40:25 +00002172/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002173
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002174PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002175"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002176Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002177
Barry Warsaw53699e91996-12-10 23:23:01 +00002178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002179posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002180{
2181 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002182 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183 return NULL;
2184 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002185 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002186}
2187
Martin v. Löwis114619e2002-10-07 06:44:21 +00002188#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2189static void
2190free_string_array(char **array, int count)
2191{
2192 int i;
2193 for (i = 0; i < count; i++)
2194 PyMem_Free(array[i]);
2195 PyMem_DEL(array);
2196}
2197#endif
2198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002199
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002200#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002201PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002202"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002203Execute an executable path with arguments, replacing current process.\n\
2204\n\
2205 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002206 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207
Barry Warsaw53699e91996-12-10 23:23:01 +00002208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002209posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002210{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002211 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002212 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002213 char **argvlist;
2214 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002215 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002216
Guido van Rossum89b33251993-10-22 14:26:06 +00002217 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002218 argv is a list or tuple of strings. */
2219
Martin v. Löwis114619e2002-10-07 06:44:21 +00002220 if (!PyArg_ParseTuple(args, "etO:execv",
2221 Py_FileSystemDefaultEncoding,
2222 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002223 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 if (PyList_Check(argv)) {
2225 argc = PyList_Size(argv);
2226 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002227 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002228 else if (PyTuple_Check(argv)) {
2229 argc = PyTuple_Size(argv);
2230 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002231 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002232 else {
Fred Drake661ea262000-10-24 19:57:45 +00002233 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002234 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002235 return NULL;
2236 }
2237
2238 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002239 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002240 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002241 return NULL;
2242 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002243
Barry Warsaw53699e91996-12-10 23:23:01 +00002244 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002245 if (argvlist == NULL) {
2246 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002247 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002248 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002249 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002250 if (!PyArg_Parse((*getitem)(argv, i), "et",
2251 Py_FileSystemDefaultEncoding,
2252 &argvlist[i])) {
2253 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002254 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002255 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002256 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002257 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002258
Guido van Rossum85e3b011991-06-03 12:42:10 +00002259 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002260 }
2261 argvlist[argc] = NULL;
2262
Guido van Rossumb6775db1994-08-01 11:34:53 +00002263#ifdef BAD_EXEC_PROTOTYPES
2264 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002265#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002266 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002267#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002268
Guido van Rossum85e3b011991-06-03 12:42:10 +00002269 /* If we get here it's definitely an error */
2270
Martin v. Löwis114619e2002-10-07 06:44:21 +00002271 free_string_array(argvlist, argc);
2272 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002273 return posix_error();
2274}
2275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002278"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279Execute a path with arguments and environment, replacing current process.\n\
2280\n\
2281 path: path of executable file\n\
2282 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002283 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002284
Barry Warsaw53699e91996-12-10 23:23:01 +00002285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002286posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002287{
2288 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002289 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002290 char **argvlist;
2291 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002292 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002293 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002294 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002295 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002296
2297 /* execve has three arguments: (path, argv, env), where
2298 argv is a list or tuple of strings and env is a dictionary
2299 like posix.environ. */
2300
Martin v. Löwis114619e2002-10-07 06:44:21 +00002301 if (!PyArg_ParseTuple(args, "etOO:execve",
2302 Py_FileSystemDefaultEncoding,
2303 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002304 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002305 if (PyList_Check(argv)) {
2306 argc = PyList_Size(argv);
2307 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002308 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002309 else if (PyTuple_Check(argv)) {
2310 argc = PyTuple_Size(argv);
2311 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002312 }
2313 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002314 PyErr_SetString(PyExc_TypeError,
2315 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002316 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002317 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002318 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002319 PyErr_SetString(PyExc_TypeError,
2320 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002321 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002322 }
2323
Guido van Rossum50422b42000-04-26 20:34:28 +00002324 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002325 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002326 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002327 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002328 }
2329
Barry Warsaw53699e91996-12-10 23:23:01 +00002330 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002331 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002332 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002333 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 }
2335 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002336 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002337 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002338 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002339 &argvlist[i]))
2340 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002341 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002342 goto fail_1;
2343 }
2344 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002345 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002346 argvlist[argc] = NULL;
2347
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002348 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002349 if (i < 0)
2350 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002351 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002352 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002353 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002354 goto fail_1;
2355 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002356 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002357 keys = PyMapping_Keys(env);
2358 vals = PyMapping_Values(env);
2359 if (!keys || !vals)
2360 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002361 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2362 PyErr_SetString(PyExc_TypeError,
2363 "execve(): env.keys() or env.values() is not a list");
2364 goto fail_2;
2365 }
Tim Peters5aa91602002-01-30 05:46:57 +00002366
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002367 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002368 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002369 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002370
2371 key = PyList_GetItem(keys, pos);
2372 val = PyList_GetItem(vals, pos);
2373 if (!key || !val)
2374 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002375
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002376 if (!PyArg_Parse(
2377 key,
2378 "s;execve() arg 3 contains a non-string key",
2379 &k) ||
2380 !PyArg_Parse(
2381 val,
2382 "s;execve() arg 3 contains a non-string value",
2383 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002384 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002385 goto fail_2;
2386 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002387
2388#if defined(PYOS_OS2)
2389 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2390 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2391#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002392 len = PyString_Size(key) + PyString_Size(val) + 2;
2393 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002394 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002395 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002396 goto fail_2;
2397 }
Tim Petersc8996f52001-12-03 20:41:00 +00002398 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002399 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002400#if defined(PYOS_OS2)
2401 }
2402#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002403 }
2404 envlist[envc] = 0;
2405
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406
2407#ifdef BAD_EXEC_PROTOTYPES
2408 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002409#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002410 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002411#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002412
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002413 /* If we get here it's definitely an error */
2414
2415 (void) posix_error();
2416
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002417 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002418 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002419 PyMem_DEL(envlist[envc]);
2420 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002421 fail_1:
2422 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002423 Py_XDECREF(vals);
2424 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002425 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002426 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002427 return NULL;
2428}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002429#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002431
Guido van Rossuma1065681999-01-25 23:20:23 +00002432#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002433PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002434"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002435Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002436\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002437 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002438 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002439 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002440
2441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002442posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002443{
2444 char *path;
2445 PyObject *argv;
2446 char **argvlist;
2447 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002448 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002449 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002450
2451 /* spawnv has three arguments: (mode, path, argv), where
2452 argv is a list or tuple of strings. */
2453
Martin v. Löwis114619e2002-10-07 06:44:21 +00002454 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2455 Py_FileSystemDefaultEncoding,
2456 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002457 return NULL;
2458 if (PyList_Check(argv)) {
2459 argc = PyList_Size(argv);
2460 getitem = PyList_GetItem;
2461 }
2462 else if (PyTuple_Check(argv)) {
2463 argc = PyTuple_Size(argv);
2464 getitem = PyTuple_GetItem;
2465 }
2466 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002467 PyErr_SetString(PyExc_TypeError,
2468 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002469 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002470 return NULL;
2471 }
2472
2473 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002474 if (argvlist == NULL) {
2475 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002476 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002477 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002478 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002479 if (!PyArg_Parse((*getitem)(argv, i), "et",
2480 Py_FileSystemDefaultEncoding,
2481 &argvlist[i])) {
2482 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002483 PyErr_SetString(
2484 PyExc_TypeError,
2485 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002486 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002487 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002488 }
2489 }
2490 argvlist[argc] = NULL;
2491
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002492#if defined(PYOS_OS2) && defined(PYCC_GCC)
2493 Py_BEGIN_ALLOW_THREADS
2494 spawnval = spawnv(mode, path, argvlist);
2495 Py_END_ALLOW_THREADS
2496#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002497 if (mode == _OLD_P_OVERLAY)
2498 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002499
Tim Peters25059d32001-12-07 20:35:43 +00002500 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002501 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002502 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002503#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002504
Martin v. Löwis114619e2002-10-07 06:44:21 +00002505 free_string_array(argvlist, argc);
2506 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002507
Fred Drake699f3522000-06-29 21:12:41 +00002508 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002509 return posix_error();
2510 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002511#if SIZEOF_LONG == SIZEOF_VOID_P
2512 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002513#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002514 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002515#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002516}
2517
2518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002519PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002520"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002521Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002522\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002523 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002524 path: path of executable file\n\
2525 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002526 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002527
2528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002529posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002530{
2531 char *path;
2532 PyObject *argv, *env;
2533 char **argvlist;
2534 char **envlist;
2535 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2536 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002537 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002538 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002539 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002540
2541 /* spawnve has four arguments: (mode, path, argv, env), where
2542 argv is a list or tuple of strings and env is a dictionary
2543 like posix.environ. */
2544
Martin v. Löwis114619e2002-10-07 06:44:21 +00002545 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2546 Py_FileSystemDefaultEncoding,
2547 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002548 return NULL;
2549 if (PyList_Check(argv)) {
2550 argc = PyList_Size(argv);
2551 getitem = PyList_GetItem;
2552 }
2553 else if (PyTuple_Check(argv)) {
2554 argc = PyTuple_Size(argv);
2555 getitem = PyTuple_GetItem;
2556 }
2557 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002558 PyErr_SetString(PyExc_TypeError,
2559 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002560 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002561 }
2562 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002563 PyErr_SetString(PyExc_TypeError,
2564 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002565 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002566 }
2567
2568 argvlist = PyMem_NEW(char *, argc+1);
2569 if (argvlist == NULL) {
2570 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002571 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002572 }
2573 for (i = 0; i < argc; i++) {
2574 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002575 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002576 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002577 &argvlist[i]))
2578 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002579 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002580 goto fail_1;
2581 }
2582 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002583 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002584 argvlist[argc] = NULL;
2585
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002586 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002587 if (i < 0)
2588 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002589 envlist = PyMem_NEW(char *, i + 1);
2590 if (envlist == NULL) {
2591 PyErr_NoMemory();
2592 goto fail_1;
2593 }
2594 envc = 0;
2595 keys = PyMapping_Keys(env);
2596 vals = PyMapping_Values(env);
2597 if (!keys || !vals)
2598 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002599 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2600 PyErr_SetString(PyExc_TypeError,
2601 "spawnve(): env.keys() or env.values() is not a list");
2602 goto fail_2;
2603 }
Tim Peters5aa91602002-01-30 05:46:57 +00002604
Guido van Rossuma1065681999-01-25 23:20:23 +00002605 for (pos = 0; pos < i; pos++) {
2606 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002607 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002608
2609 key = PyList_GetItem(keys, pos);
2610 val = PyList_GetItem(vals, pos);
2611 if (!key || !val)
2612 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002613
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002614 if (!PyArg_Parse(
2615 key,
2616 "s;spawnve() arg 3 contains a non-string key",
2617 &k) ||
2618 !PyArg_Parse(
2619 val,
2620 "s;spawnve() arg 3 contains a non-string value",
2621 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002622 {
2623 goto fail_2;
2624 }
Tim Petersc8996f52001-12-03 20:41:00 +00002625 len = PyString_Size(key) + PyString_Size(val) + 2;
2626 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002627 if (p == NULL) {
2628 PyErr_NoMemory();
2629 goto fail_2;
2630 }
Tim Petersc8996f52001-12-03 20:41:00 +00002631 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002632 envlist[envc++] = p;
2633 }
2634 envlist[envc] = 0;
2635
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002636#if defined(PYOS_OS2) && defined(PYCC_GCC)
2637 Py_BEGIN_ALLOW_THREADS
2638 spawnval = spawnve(mode, path, argvlist, envlist);
2639 Py_END_ALLOW_THREADS
2640#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002641 if (mode == _OLD_P_OVERLAY)
2642 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002643
2644 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002645 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002646 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002647#endif
Tim Peters25059d32001-12-07 20:35:43 +00002648
Fred Drake699f3522000-06-29 21:12:41 +00002649 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002650 (void) posix_error();
2651 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002652#if SIZEOF_LONG == SIZEOF_VOID_P
2653 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002654#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002655 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002656#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002657
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002658 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002659 while (--envc >= 0)
2660 PyMem_DEL(envlist[envc]);
2661 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002662 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002663 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002664 Py_XDECREF(vals);
2665 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002666 fail_0:
2667 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002668 return res;
2669}
2670#endif /* HAVE_SPAWNV */
2671
2672
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002673#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002674PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002675"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002676Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2677\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002679
2680static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002681posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002682{
Neal Norwitze241ce82003-02-17 18:17:05 +00002683 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002684 if (pid == -1)
2685 return posix_error();
2686 PyOS_AfterFork();
2687 return PyInt_FromLong((long)pid);
2688}
2689#endif
2690
2691
Guido van Rossumad0ee831995-03-01 10:34:45 +00002692#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002693PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002694"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002695Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002696Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002697
Barry Warsaw53699e91996-12-10 23:23:01 +00002698static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002699posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002700{
Neal Norwitze241ce82003-02-17 18:17:05 +00002701 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002702 if (pid == -1)
2703 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002704 if (pid == 0)
2705 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002706 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002707}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002708#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002709
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002710#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002711#ifdef HAVE_PTY_H
2712#include <pty.h>
2713#else
2714#ifdef HAVE_LIBUTIL_H
2715#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002716#endif /* HAVE_LIBUTIL_H */
2717#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002718#ifdef HAVE_STROPTS_H
2719#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002720#endif
2721#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002722
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002723#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002725"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002727
2728static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002729posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002730{
2731 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002732#ifndef HAVE_OPENPTY
2733 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002734#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002735#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002736 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002737#ifdef sun
2738 extern char *ptsname();
2739#endif
2740#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002741
Thomas Wouters70c21a12000-07-14 14:28:33 +00002742#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002743 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2744 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002745#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002746 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2747 if (slave_name == NULL)
2748 return posix_error();
2749
2750 slave_fd = open(slave_name, O_RDWR);
2751 if (slave_fd < 0)
2752 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002753#else
2754 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2755 if (master_fd < 0)
2756 return posix_error();
2757 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002758 /* change permission of slave */
2759 if (grantpt(master_fd) < 0) {
2760 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002761 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002762 }
2763 /* unlock slave */
2764 if (unlockpt(master_fd) < 0) {
2765 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002766 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002767 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002768 signal(SIGCHLD, sig_saved);
2769 slave_name = ptsname(master_fd); /* get name of slave */
2770 if (slave_name == NULL)
2771 return posix_error();
2772 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2773 if (slave_fd < 0)
2774 return posix_error();
2775#ifndef __CYGWIN__
2776 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2777 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002778#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002779 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002780#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002781#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002782#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002783
Fred Drake8cef4cf2000-06-28 16:40:38 +00002784 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002785
Fred Drake8cef4cf2000-06-28 16:40:38 +00002786}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002787#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002788
2789#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002791"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002792Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2793Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002794To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002795
2796static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002797posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002798{
2799 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002800
Fred Drake8cef4cf2000-06-28 16:40:38 +00002801 pid = forkpty(&master_fd, NULL, NULL, NULL);
2802 if (pid == -1)
2803 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002804 if (pid == 0)
2805 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002806 return Py_BuildValue("(ii)", pid, master_fd);
2807}
2808#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002809
Guido van Rossumad0ee831995-03-01 10:34:45 +00002810#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002811PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002812"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002814
Barry Warsaw53699e91996-12-10 23:23:01 +00002815static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002816posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002817{
Barry Warsaw53699e91996-12-10 23:23:01 +00002818 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002819}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002820#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002822
Guido van Rossumad0ee831995-03-01 10:34:45 +00002823#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002825"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002826Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002827
Barry Warsaw53699e91996-12-10 23:23:01 +00002828static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002829posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002830{
Barry Warsaw53699e91996-12-10 23:23:01 +00002831 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002832}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002833#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Guido van Rossumad0ee831995-03-01 10:34:45 +00002836#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002838"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839Return the current process's 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_getgid(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)getgid());
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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002849PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002850"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002852
Barry Warsaw53699e91996-12-10 23:23:01 +00002853static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002854posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002855{
Barry Warsaw53699e91996-12-10 23:23:01 +00002856 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002857}
2858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002859
Fred Drakec9680921999-12-13 16:37:25 +00002860#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002862"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002864
2865static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002866posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002867{
2868 PyObject *result = NULL;
2869
Fred Drakec9680921999-12-13 16:37:25 +00002870#ifdef NGROUPS_MAX
2871#define MAX_GROUPS NGROUPS_MAX
2872#else
2873 /* defined to be 16 on Solaris7, so this should be a small number */
2874#define MAX_GROUPS 64
2875#endif
2876 gid_t grouplist[MAX_GROUPS];
2877 int n;
2878
2879 n = getgroups(MAX_GROUPS, grouplist);
2880 if (n < 0)
2881 posix_error();
2882 else {
2883 result = PyList_New(n);
2884 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002885 int i;
2886 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002887 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002888 if (o == NULL) {
2889 Py_DECREF(result);
2890 result = NULL;
2891 break;
2892 }
2893 PyList_SET_ITEM(result, i, o);
2894 }
2895 }
2896 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002897
Fred Drakec9680921999-12-13 16:37:25 +00002898 return result;
2899}
2900#endif
2901
Martin v. Löwis606edc12002-06-13 21:09:11 +00002902#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002903PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002904"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002905Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002906
2907static PyObject *
2908posix_getpgid(PyObject *self, PyObject *args)
2909{
2910 int pid, pgid;
2911 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2912 return NULL;
2913 pgid = getpgid(pid);
2914 if (pgid < 0)
2915 return posix_error();
2916 return PyInt_FromLong((long)pgid);
2917}
2918#endif /* HAVE_GETPGID */
2919
2920
Guido van Rossumb6775db1994-08-01 11:34:53 +00002921#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002922PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002923"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002924Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002925
Barry Warsaw53699e91996-12-10 23:23:01 +00002926static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002927posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002928{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002929#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002930 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002931#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002932 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002933#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002934}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002935#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002937
Guido van Rossumb6775db1994-08-01 11:34:53 +00002938#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002940"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002941Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002942
Barry Warsaw53699e91996-12-10 23:23:01 +00002943static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002944posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002945{
Guido van Rossum64933891994-10-20 21:56:42 +00002946#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002947 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002948#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002949 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002950#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002951 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002952 Py_INCREF(Py_None);
2953 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002954}
2955
Guido van Rossumb6775db1994-08-01 11:34:53 +00002956#endif /* HAVE_SETPGRP */
2957
Guido van Rossumad0ee831995-03-01 10:34:45 +00002958#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002960"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002962
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002964posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002965{
Barry Warsaw53699e91996-12-10 23:23:01 +00002966 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002967}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002968#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002970
Fred Drake12c6e2d1999-12-14 21:25:03 +00002971#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002972PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002973"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002974Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002975
2976static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002977posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002978{
Neal Norwitze241ce82003-02-17 18:17:05 +00002979 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002980 char *name;
2981 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002982
Fred Drakea30680b2000-12-06 21:24:28 +00002983 errno = 0;
2984 name = getlogin();
2985 if (name == NULL) {
2986 if (errno)
2987 posix_error();
2988 else
2989 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002990 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002991 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002992 else
2993 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002994 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002995
Fred Drake12c6e2d1999-12-14 21:25:03 +00002996 return result;
2997}
2998#endif
2999
Guido van Rossumad0ee831995-03-01 10:34:45 +00003000#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003001PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003002"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003003Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003004
Barry Warsaw53699e91996-12-10 23:23:01 +00003005static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003006posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003007{
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003009}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003010#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003012
Guido van Rossumad0ee831995-03-01 10:34:45 +00003013#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003014PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003015"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003016Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003017
Barry Warsaw53699e91996-12-10 23:23:01 +00003018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003019posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003020{
3021 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003022 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003023 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003024#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003025 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3026 APIRET rc;
3027 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003028 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003029
3030 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3031 APIRET rc;
3032 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003033 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003034
3035 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003036 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003037#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003038 if (kill(pid, sig) == -1)
3039 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003040#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 Py_INCREF(Py_None);
3042 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003043}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003044#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003045
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003046#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003047PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003048"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003049Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003050
3051static PyObject *
3052posix_killpg(PyObject *self, PyObject *args)
3053{
3054 int pgid, sig;
3055 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3056 return NULL;
3057 if (killpg(pgid, sig) == -1)
3058 return posix_error();
3059 Py_INCREF(Py_None);
3060 return Py_None;
3061}
3062#endif
3063
Guido van Rossumc0125471996-06-28 18:55:32 +00003064#ifdef HAVE_PLOCK
3065
3066#ifdef HAVE_SYS_LOCK_H
3067#include <sys/lock.h>
3068#endif
3069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003070PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003071"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003072Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003073
Barry Warsaw53699e91996-12-10 23:23:01 +00003074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003075posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003076{
3077 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003078 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003079 return NULL;
3080 if (plock(op) == -1)
3081 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003082 Py_INCREF(Py_None);
3083 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003084}
3085#endif
3086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003087
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003088#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003090"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003091Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003092
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003093#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003094#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003095static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003096async_system(const char *command)
3097{
3098 char *p, errormsg[256], args[1024];
3099 RESULTCODES rcodes;
3100 APIRET rc;
3101 char *shell = getenv("COMSPEC");
3102 if (!shell)
3103 shell = "cmd";
3104
3105 strcpy(args, shell);
3106 p = &args[ strlen(args)+1 ];
3107 strcpy(p, "/c ");
3108 strcat(p, command);
3109 p += strlen(p) + 1;
3110 *p = '\0';
3111
3112 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003113 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003114 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003115 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003116 &rcodes, shell);
3117 return rc;
3118}
3119
Guido van Rossumd48f2521997-12-05 22:19:34 +00003120static FILE *
3121popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003122{
3123 HFILE rhan, whan;
3124 FILE *retfd = NULL;
3125 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3126
Guido van Rossumd48f2521997-12-05 22:19:34 +00003127 if (rc != NO_ERROR) {
3128 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003129 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003130 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003131
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003132 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3133 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003134
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003135 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3136 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003137
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003138 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3139 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003140
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003141 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003142 }
3143
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003144 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3145 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003146
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003147 if (rc == NO_ERROR)
3148 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3149
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003150 close(oldfd); /* And Close Saved STDOUT Handle */
3151 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003152
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003153 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3154 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003155
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003156 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3157 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003158
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003159 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3160 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003161
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003162 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003163 }
3164
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003165 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3166 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003167
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003168 if (rc == NO_ERROR)
3169 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003171 close(oldfd); /* And Close Saved STDIN Handle */
3172 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003173
Guido van Rossumd48f2521997-12-05 22:19:34 +00003174 } else {
3175 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003176 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003177 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003178}
3179
3180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003181posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003182{
3183 char *name;
3184 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003185 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003186 FILE *fp;
3187 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003188 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003189 return NULL;
3190 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003191 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003192 Py_END_ALLOW_THREADS
3193 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003194 return os2_error(err);
3195
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003196 f = PyFile_FromFile(fp, name, mode, fclose);
3197 if (f != NULL)
3198 PyFile_SetBufSize(f, bufsize);
3199 return f;
3200}
3201
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003202#elif defined(PYCC_GCC)
3203
3204/* standard posix version of popen() support */
3205static PyObject *
3206posix_popen(PyObject *self, PyObject *args)
3207{
3208 char *name;
3209 char *mode = "r";
3210 int bufsize = -1;
3211 FILE *fp;
3212 PyObject *f;
3213 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3214 return NULL;
3215 Py_BEGIN_ALLOW_THREADS
3216 fp = popen(name, mode);
3217 Py_END_ALLOW_THREADS
3218 if (fp == NULL)
3219 return posix_error();
3220 f = PyFile_FromFile(fp, name, mode, pclose);
3221 if (f != NULL)
3222 PyFile_SetBufSize(f, bufsize);
3223 return f;
3224}
3225
3226/* fork() under OS/2 has lots'o'warts
3227 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3228 * most of this code is a ripoff of the win32 code, but using the
3229 * capabilities of EMX's C library routines
3230 */
3231
3232/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3233#define POPEN_1 1
3234#define POPEN_2 2
3235#define POPEN_3 3
3236#define POPEN_4 4
3237
3238static PyObject *_PyPopen(char *, int, int, int);
3239static int _PyPclose(FILE *file);
3240
3241/*
3242 * Internal dictionary mapping popen* file pointers to process handles,
3243 * for use when retrieving the process exit code. See _PyPclose() below
3244 * for more information on this dictionary's use.
3245 */
3246static PyObject *_PyPopenProcs = NULL;
3247
3248/* os2emx version of popen2()
3249 *
3250 * The result of this function is a pipe (file) connected to the
3251 * process's stdin, and a pipe connected to the process's stdout.
3252 */
3253
3254static PyObject *
3255os2emx_popen2(PyObject *self, PyObject *args)
3256{
3257 PyObject *f;
3258 int tm=0;
3259
3260 char *cmdstring;
3261 char *mode = "t";
3262 int bufsize = -1;
3263 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3264 return NULL;
3265
3266 if (*mode == 't')
3267 tm = O_TEXT;
3268 else if (*mode != 'b') {
3269 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3270 return NULL;
3271 } else
3272 tm = O_BINARY;
3273
3274 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3275
3276 return f;
3277}
3278
3279/*
3280 * Variation on os2emx.popen2
3281 *
3282 * The result of this function is 3 pipes - the process's stdin,
3283 * stdout and stderr
3284 */
3285
3286static PyObject *
3287os2emx_popen3(PyObject *self, PyObject *args)
3288{
3289 PyObject *f;
3290 int tm = 0;
3291
3292 char *cmdstring;
3293 char *mode = "t";
3294 int bufsize = -1;
3295 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3296 return NULL;
3297
3298 if (*mode == 't')
3299 tm = O_TEXT;
3300 else if (*mode != 'b') {
3301 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3302 return NULL;
3303 } else
3304 tm = O_BINARY;
3305
3306 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3307
3308 return f;
3309}
3310
3311/*
3312 * Variation on os2emx.popen2
3313 *
3314 * The result of this function is 2 pipes - the processes stdin,
3315 * and stdout+stderr combined as a single pipe.
3316 */
3317
3318static PyObject *
3319os2emx_popen4(PyObject *self, PyObject *args)
3320{
3321 PyObject *f;
3322 int tm = 0;
3323
3324 char *cmdstring;
3325 char *mode = "t";
3326 int bufsize = -1;
3327 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3328 return NULL;
3329
3330 if (*mode == 't')
3331 tm = O_TEXT;
3332 else if (*mode != 'b') {
3333 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3334 return NULL;
3335 } else
3336 tm = O_BINARY;
3337
3338 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3339
3340 return f;
3341}
3342
3343/* a couple of structures for convenient handling of multiple
3344 * file handles and pipes
3345 */
3346struct file_ref
3347{
3348 int handle;
3349 int flags;
3350};
3351
3352struct pipe_ref
3353{
3354 int rd;
3355 int wr;
3356};
3357
3358/* The following code is derived from the win32 code */
3359
3360static PyObject *
3361_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3362{
3363 struct file_ref stdio[3];
3364 struct pipe_ref p_fd[3];
3365 FILE *p_s[3];
3366 int file_count, i, pipe_err, pipe_pid;
3367 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3368 PyObject *f, *p_f[3];
3369
3370 /* file modes for subsequent fdopen's on pipe handles */
3371 if (mode == O_TEXT)
3372 {
3373 rd_mode = "rt";
3374 wr_mode = "wt";
3375 }
3376 else
3377 {
3378 rd_mode = "rb";
3379 wr_mode = "wb";
3380 }
3381
3382 /* prepare shell references */
3383 if ((shell = getenv("EMXSHELL")) == NULL)
3384 if ((shell = getenv("COMSPEC")) == NULL)
3385 {
3386 errno = ENOENT;
3387 return posix_error();
3388 }
3389
3390 sh_name = _getname(shell);
3391 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3392 opt = "/c";
3393 else
3394 opt = "-c";
3395
3396 /* save current stdio fds + their flags, and set not inheritable */
3397 i = pipe_err = 0;
3398 while (pipe_err >= 0 && i < 3)
3399 {
3400 pipe_err = stdio[i].handle = dup(i);
3401 stdio[i].flags = fcntl(i, F_GETFD, 0);
3402 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3403 i++;
3404 }
3405 if (pipe_err < 0)
3406 {
3407 /* didn't get them all saved - clean up and bail out */
3408 int saved_err = errno;
3409 while (i-- > 0)
3410 {
3411 close(stdio[i].handle);
3412 }
3413 errno = saved_err;
3414 return posix_error();
3415 }
3416
3417 /* create pipe ends */
3418 file_count = 2;
3419 if (n == POPEN_3)
3420 file_count = 3;
3421 i = pipe_err = 0;
3422 while ((pipe_err == 0) && (i < file_count))
3423 pipe_err = pipe((int *)&p_fd[i++]);
3424 if (pipe_err < 0)
3425 {
3426 /* didn't get them all made - clean up and bail out */
3427 while (i-- > 0)
3428 {
3429 close(p_fd[i].wr);
3430 close(p_fd[i].rd);
3431 }
3432 errno = EPIPE;
3433 return posix_error();
3434 }
3435
3436 /* change the actual standard IO streams over temporarily,
3437 * making the retained pipe ends non-inheritable
3438 */
3439 pipe_err = 0;
3440
3441 /* - stdin */
3442 if (dup2(p_fd[0].rd, 0) == 0)
3443 {
3444 close(p_fd[0].rd);
3445 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3446 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3447 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3448 {
3449 close(p_fd[0].wr);
3450 pipe_err = -1;
3451 }
3452 }
3453 else
3454 {
3455 pipe_err = -1;
3456 }
3457
3458 /* - stdout */
3459 if (pipe_err == 0)
3460 {
3461 if (dup2(p_fd[1].wr, 1) == 1)
3462 {
3463 close(p_fd[1].wr);
3464 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3465 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3466 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3467 {
3468 close(p_fd[1].rd);
3469 pipe_err = -1;
3470 }
3471 }
3472 else
3473 {
3474 pipe_err = -1;
3475 }
3476 }
3477
3478 /* - stderr, as required */
3479 if (pipe_err == 0)
3480 switch (n)
3481 {
3482 case POPEN_3:
3483 {
3484 if (dup2(p_fd[2].wr, 2) == 2)
3485 {
3486 close(p_fd[2].wr);
3487 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3488 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3489 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3490 {
3491 close(p_fd[2].rd);
3492 pipe_err = -1;
3493 }
3494 }
3495 else
3496 {
3497 pipe_err = -1;
3498 }
3499 break;
3500 }
3501
3502 case POPEN_4:
3503 {
3504 if (dup2(1, 2) != 2)
3505 {
3506 pipe_err = -1;
3507 }
3508 break;
3509 }
3510 }
3511
3512 /* spawn the child process */
3513 if (pipe_err == 0)
3514 {
3515 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3516 if (pipe_pid == -1)
3517 {
3518 pipe_err = -1;
3519 }
3520 else
3521 {
3522 /* save the PID into the FILE structure
3523 * NOTE: this implementation doesn't actually
3524 * take advantage of this, but do it for
3525 * completeness - AIM Apr01
3526 */
3527 for (i = 0; i < file_count; i++)
3528 p_s[i]->_pid = pipe_pid;
3529 }
3530 }
3531
3532 /* reset standard IO to normal */
3533 for (i = 0; i < 3; i++)
3534 {
3535 dup2(stdio[i].handle, i);
3536 fcntl(i, F_SETFD, stdio[i].flags);
3537 close(stdio[i].handle);
3538 }
3539
3540 /* if any remnant problems, clean up and bail out */
3541 if (pipe_err < 0)
3542 {
3543 for (i = 0; i < 3; i++)
3544 {
3545 close(p_fd[i].rd);
3546 close(p_fd[i].wr);
3547 }
3548 errno = EPIPE;
3549 return posix_error_with_filename(cmdstring);
3550 }
3551
3552 /* build tuple of file objects to return */
3553 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3554 PyFile_SetBufSize(p_f[0], bufsize);
3555 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3556 PyFile_SetBufSize(p_f[1], bufsize);
3557 if (n == POPEN_3)
3558 {
3559 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3560 PyFile_SetBufSize(p_f[0], bufsize);
3561 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3562 }
3563 else
3564 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3565
3566 /*
3567 * Insert the files we've created into the process dictionary
3568 * all referencing the list with the process handle and the
3569 * initial number of files (see description below in _PyPclose).
3570 * Since if _PyPclose later tried to wait on a process when all
3571 * handles weren't closed, it could create a deadlock with the
3572 * child, we spend some energy here to try to ensure that we
3573 * either insert all file handles into the dictionary or none
3574 * at all. It's a little clumsy with the various popen modes
3575 * and variable number of files involved.
3576 */
3577 if (!_PyPopenProcs)
3578 {
3579 _PyPopenProcs = PyDict_New();
3580 }
3581
3582 if (_PyPopenProcs)
3583 {
3584 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3585 int ins_rc[3];
3586
3587 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3588 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3589
3590 procObj = PyList_New(2);
3591 pidObj = PyInt_FromLong((long) pipe_pid);
3592 intObj = PyInt_FromLong((long) file_count);
3593
3594 if (procObj && pidObj && intObj)
3595 {
3596 PyList_SetItem(procObj, 0, pidObj);
3597 PyList_SetItem(procObj, 1, intObj);
3598
3599 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3600 if (fileObj[0])
3601 {
3602 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3603 fileObj[0],
3604 procObj);
3605 }
3606 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3607 if (fileObj[1])
3608 {
3609 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3610 fileObj[1],
3611 procObj);
3612 }
3613 if (file_count >= 3)
3614 {
3615 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3616 if (fileObj[2])
3617 {
3618 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3619 fileObj[2],
3620 procObj);
3621 }
3622 }
3623
3624 if (ins_rc[0] < 0 || !fileObj[0] ||
3625 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3626 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3627 {
3628 /* Something failed - remove any dictionary
3629 * entries that did make it.
3630 */
3631 if (!ins_rc[0] && fileObj[0])
3632 {
3633 PyDict_DelItem(_PyPopenProcs,
3634 fileObj[0]);
3635 }
3636 if (!ins_rc[1] && fileObj[1])
3637 {
3638 PyDict_DelItem(_PyPopenProcs,
3639 fileObj[1]);
3640 }
3641 if (!ins_rc[2] && fileObj[2])
3642 {
3643 PyDict_DelItem(_PyPopenProcs,
3644 fileObj[2]);
3645 }
3646 }
3647 }
3648
3649 /*
3650 * Clean up our localized references for the dictionary keys
3651 * and value since PyDict_SetItem will Py_INCREF any copies
3652 * that got placed in the dictionary.
3653 */
3654 Py_XDECREF(procObj);
3655 Py_XDECREF(fileObj[0]);
3656 Py_XDECREF(fileObj[1]);
3657 Py_XDECREF(fileObj[2]);
3658 }
3659
3660 /* Child is launched. */
3661 return f;
3662}
3663
3664/*
3665 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3666 * exit code for the child process and return as a result of the close.
3667 *
3668 * This function uses the _PyPopenProcs dictionary in order to map the
3669 * input file pointer to information about the process that was
3670 * originally created by the popen* call that created the file pointer.
3671 * The dictionary uses the file pointer as a key (with one entry
3672 * inserted for each file returned by the original popen* call) and a
3673 * single list object as the value for all files from a single call.
3674 * The list object contains the Win32 process handle at [0], and a file
3675 * count at [1], which is initialized to the total number of file
3676 * handles using that list.
3677 *
3678 * This function closes whichever handle it is passed, and decrements
3679 * the file count in the dictionary for the process handle pointed to
3680 * by this file. On the last close (when the file count reaches zero),
3681 * this function will wait for the child process and then return its
3682 * exit code as the result of the close() operation. This permits the
3683 * files to be closed in any order - it is always the close() of the
3684 * final handle that will return the exit code.
3685 */
3686
3687 /* RED_FLAG 31-Aug-2000 Tim
3688 * This is always called (today!) between a pair of
3689 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3690 * macros. So the thread running this has no valid thread state, as
3691 * far as Python is concerned. However, this calls some Python API
3692 * functions that cannot be called safely without a valid thread
3693 * state, in particular PyDict_GetItem.
3694 * As a temporary hack (although it may last for years ...), we
3695 * *rely* on not having a valid thread state in this function, in
3696 * order to create our own "from scratch".
3697 * This will deadlock if _PyPclose is ever called by a thread
3698 * holding the global lock.
3699 * (The OS/2 EMX thread support appears to cover the case where the
3700 * lock is already held - AIM Apr01)
3701 */
3702
3703static int _PyPclose(FILE *file)
3704{
3705 int result;
3706 int exit_code;
3707 int pipe_pid;
3708 PyObject *procObj, *pidObj, *intObj, *fileObj;
3709 int file_count;
3710#ifdef WITH_THREAD
3711 PyInterpreterState* pInterpreterState;
3712 PyThreadState* pThreadState;
3713#endif
3714
3715 /* Close the file handle first, to ensure it can't block the
3716 * child from exiting if it's the last handle.
3717 */
3718 result = fclose(file);
3719
3720#ifdef WITH_THREAD
3721 /* Bootstrap a valid thread state into existence. */
3722 pInterpreterState = PyInterpreterState_New();
3723 if (!pInterpreterState) {
3724 /* Well, we're hosed now! We don't have a thread
3725 * state, so can't call a nice error routine, or raise
3726 * an exception. Just die.
3727 */
3728 Py_FatalError("unable to allocate interpreter state "
3729 "when closing popen object.");
3730 return -1; /* unreachable */
3731 }
3732 pThreadState = PyThreadState_New(pInterpreterState);
3733 if (!pThreadState) {
3734 Py_FatalError("unable to allocate thread state "
3735 "when closing popen object.");
3736 return -1; /* unreachable */
3737 }
3738 /* Grab the global lock. Note that this will deadlock if the
3739 * current thread already has the lock! (see RED_FLAG comments
3740 * before this function)
3741 */
3742 PyEval_RestoreThread(pThreadState);
3743#endif
3744
3745 if (_PyPopenProcs)
3746 {
3747 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3748 (procObj = PyDict_GetItem(_PyPopenProcs,
3749 fileObj)) != NULL &&
3750 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3751 (intObj = PyList_GetItem(procObj,1)) != NULL)
3752 {
3753 pipe_pid = (int) PyInt_AsLong(pidObj);
3754 file_count = (int) PyInt_AsLong(intObj);
3755
3756 if (file_count > 1)
3757 {
3758 /* Still other files referencing process */
3759 file_count--;
3760 PyList_SetItem(procObj,1,
3761 PyInt_FromLong((long) file_count));
3762 }
3763 else
3764 {
3765 /* Last file for this process */
3766 if (result != EOF &&
3767 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3768 {
3769 /* extract exit status */
3770 if (WIFEXITED(exit_code))
3771 {
3772 result = WEXITSTATUS(exit_code);
3773 }
3774 else
3775 {
3776 errno = EPIPE;
3777 result = -1;
3778 }
3779 }
3780 else
3781 {
3782 /* Indicate failure - this will cause the file object
3783 * to raise an I/O error and translate the last
3784 * error code from errno. We do have a problem with
3785 * last errors that overlap the normal errno table,
3786 * but that's a consistent problem with the file object.
3787 */
3788 result = -1;
3789 }
3790 }
3791
3792 /* Remove this file pointer from dictionary */
3793 PyDict_DelItem(_PyPopenProcs, fileObj);
3794
3795 if (PyDict_Size(_PyPopenProcs) == 0)
3796 {
3797 Py_DECREF(_PyPopenProcs);
3798 _PyPopenProcs = NULL;
3799 }
3800
3801 } /* if object retrieval ok */
3802
3803 Py_XDECREF(fileObj);
3804 } /* if _PyPopenProcs */
3805
3806#ifdef WITH_THREAD
3807 /* Tear down the thread & interpreter states.
3808 * Note that interpreter state clear & delete functions automatically
3809 * call the thread clear & delete functions, and indeed insist on
3810 * doing that themselves. The lock must be held during the clear, but
3811 * need not be held during the delete.
3812 */
3813 PyInterpreterState_Clear(pInterpreterState);
3814 PyEval_ReleaseThread(pThreadState);
3815 PyInterpreterState_Delete(pInterpreterState);
3816#endif
3817
3818 return result;
3819}
3820
3821#endif /* PYCC_??? */
3822
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003823#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003824
3825/*
3826 * Portable 'popen' replacement for Win32.
3827 *
3828 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3829 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003830 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003831 */
3832
3833#include <malloc.h>
3834#include <io.h>
3835#include <fcntl.h>
3836
3837/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3838#define POPEN_1 1
3839#define POPEN_2 2
3840#define POPEN_3 3
3841#define POPEN_4 4
3842
3843static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003844static int _PyPclose(FILE *file);
3845
3846/*
3847 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003848 * for use when retrieving the process exit code. See _PyPclose() below
3849 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003850 */
3851static PyObject *_PyPopenProcs = NULL;
3852
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003853
3854/* popen that works from a GUI.
3855 *
3856 * The result of this function is a pipe (file) connected to the
3857 * processes stdin or stdout, depending on the requested mode.
3858 */
3859
3860static PyObject *
3861posix_popen(PyObject *self, PyObject *args)
3862{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003863 PyObject *f, *s;
3864 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003865
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003866 char *cmdstring;
3867 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003868 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003869 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003870 return NULL;
3871
3872 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003873
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003874 if (*mode == 'r')
3875 tm = _O_RDONLY;
3876 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003877 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003878 return NULL;
3879 } else
3880 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003881
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003882 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003883 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003884 return NULL;
3885 }
3886
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003887 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003888 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003889 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003890 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003891 else
3892 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3893
3894 return f;
3895}
3896
3897/* Variation on win32pipe.popen
3898 *
3899 * The result of this function is a pipe (file) connected to the
3900 * process's stdin, and a pipe connected to the process's stdout.
3901 */
3902
3903static PyObject *
3904win32_popen2(PyObject *self, PyObject *args)
3905{
3906 PyObject *f;
3907 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003908
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003909 char *cmdstring;
3910 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003911 int bufsize = -1;
3912 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003913 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003914
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003915 if (*mode == 't')
3916 tm = _O_TEXT;
3917 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003918 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003919 return NULL;
3920 } else
3921 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003922
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003923 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003924 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003925 return NULL;
3926 }
3927
3928 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003929
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003930 return f;
3931}
3932
3933/*
3934 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003935 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003936 * The result of this function is 3 pipes - the process's stdin,
3937 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003938 */
3939
3940static PyObject *
3941win32_popen3(PyObject *self, PyObject *args)
3942{
3943 PyObject *f;
3944 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003945
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003946 char *cmdstring;
3947 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003948 int bufsize = -1;
3949 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003950 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003951
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003952 if (*mode == 't')
3953 tm = _O_TEXT;
3954 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003955 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003956 return NULL;
3957 } else
3958 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003959
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003960 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003961 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003962 return NULL;
3963 }
3964
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003965 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003966
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003967 return f;
3968}
3969
3970/*
3971 * Variation on win32pipe.popen
3972 *
Tim Peters5aa91602002-01-30 05:46:57 +00003973 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 * and stdout+stderr combined as a single pipe.
3975 */
3976
3977static PyObject *
3978win32_popen4(PyObject *self, PyObject *args)
3979{
3980 PyObject *f;
3981 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003982
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003983 char *cmdstring;
3984 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003985 int bufsize = -1;
3986 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003987 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003988
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003989 if (*mode == 't')
3990 tm = _O_TEXT;
3991 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003992 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 return NULL;
3994 } else
3995 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003996
3997 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003998 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003999 return NULL;
4000 }
4001
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004002 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004003
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004004 return f;
4005}
4006
Mark Hammond08501372001-01-31 07:30:29 +00004007static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004008_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004009 HANDLE hStdin,
4010 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004011 HANDLE hStderr,
4012 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004013{
4014 PROCESS_INFORMATION piProcInfo;
4015 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004016 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004017 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004018 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 int i;
4020 int x;
4021
4022 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004023 char *comshell;
4024
Tim Peters92e4dd82002-10-05 01:47:34 +00004025 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004026 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4027 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004028
4029 /* Explicitly check if we are using COMMAND.COM. If we are
4030 * then use the w9xpopen hack.
4031 */
4032 comshell = s1 + x;
4033 while (comshell >= s1 && *comshell != '\\')
4034 --comshell;
4035 ++comshell;
4036
4037 if (GetVersion() < 0x80000000 &&
4038 _stricmp(comshell, "command.com") != 0) {
4039 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004040 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004041 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004042 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004043 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004044 }
4045 else {
4046 /*
Tim Peters402d5982001-08-27 06:37:48 +00004047 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4048 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004049 */
Mark Hammond08501372001-01-31 07:30:29 +00004050 char modulepath[_MAX_PATH];
4051 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004052 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4053 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004054 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004055 x = i+1;
4056 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004057 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004058 strncat(modulepath,
4059 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004060 (sizeof(modulepath)/sizeof(modulepath[0]))
4061 -strlen(modulepath));
4062 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004063 /* Eeek - file-not-found - possibly an embedding
4064 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004065 */
Tim Peters5aa91602002-01-30 05:46:57 +00004066 strncpy(modulepath,
4067 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004068 sizeof(modulepath)/sizeof(modulepath[0]));
4069 if (modulepath[strlen(modulepath)-1] != '\\')
4070 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004071 strncat(modulepath,
4072 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004073 (sizeof(modulepath)/sizeof(modulepath[0]))
4074 -strlen(modulepath));
4075 /* No where else to look - raise an easily identifiable
4076 error, rather than leaving Windows to report
4077 "file not found" - as the user is probably blissfully
4078 unaware this shim EXE is used, and it will confuse them.
4079 (well, it confused me for a while ;-)
4080 */
4081 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004082 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004083 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004084 "for popen to work with your shell "
4085 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004086 szConsoleSpawn);
4087 return FALSE;
4088 }
4089 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004090 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004091 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004092 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004093
Tim Peters92e4dd82002-10-05 01:47:34 +00004094 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004095 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004096 /* To maintain correct argument passing semantics,
4097 we pass the command-line as it stands, and allow
4098 quoting to be applied. w9xpopen.exe will then
4099 use its argv vector, and re-quote the necessary
4100 args for the ultimate child process.
4101 */
Tim Peters75cdad52001-11-28 22:07:30 +00004102 PyOS_snprintf(
4103 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004104 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004105 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004106 s1,
4107 s3,
4108 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004109 /* Not passing CREATE_NEW_CONSOLE has been known to
4110 cause random failures on win9x. Specifically a
4111 dialog:
4112 "Your program accessed mem currently in use at xxx"
4113 and a hopeful warning about the stability of your
4114 system.
4115 Cost is Ctrl+C wont kill children, but anyone
4116 who cares can have a go!
4117 */
4118 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004119 }
4120 }
4121
4122 /* Could be an else here to try cmd.exe / command.com in the path
4123 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004124 else {
Tim Peters402d5982001-08-27 06:37:48 +00004125 PyErr_SetString(PyExc_RuntimeError,
4126 "Cannot locate a COMSPEC environment variable to "
4127 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004128 return FALSE;
4129 }
Tim Peters5aa91602002-01-30 05:46:57 +00004130
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4132 siStartInfo.cb = sizeof(STARTUPINFO);
4133 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4134 siStartInfo.hStdInput = hStdin;
4135 siStartInfo.hStdOutput = hStdout;
4136 siStartInfo.hStdError = hStderr;
4137 siStartInfo.wShowWindow = SW_HIDE;
4138
4139 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004140 s2,
4141 NULL,
4142 NULL,
4143 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004144 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004145 NULL,
4146 NULL,
4147 &siStartInfo,
4148 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004149 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004150 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004151
Mark Hammondb37a3732000-08-14 04:47:33 +00004152 /* Return process handle */
4153 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004154 return TRUE;
4155 }
Tim Peters402d5982001-08-27 06:37:48 +00004156 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004157 return FALSE;
4158}
4159
4160/* The following code is based off of KB: Q190351 */
4161
4162static PyObject *
4163_PyPopen(char *cmdstring, int mode, int n)
4164{
4165 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4166 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004167 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004168
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004169 SECURITY_ATTRIBUTES saAttr;
4170 BOOL fSuccess;
4171 int fd1, fd2, fd3;
4172 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004173 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004174 PyObject *f;
4175
4176 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4177 saAttr.bInheritHandle = TRUE;
4178 saAttr.lpSecurityDescriptor = NULL;
4179
4180 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4181 return win32_error("CreatePipe", NULL);
4182
4183 /* Create new output read handle and the input write handle. Set
4184 * the inheritance properties to FALSE. Otherwise, the child inherits
4185 * the these handles; resulting in non-closeable handles to the pipes
4186 * being created. */
4187 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004188 GetCurrentProcess(), &hChildStdinWrDup, 0,
4189 FALSE,
4190 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004191 if (!fSuccess)
4192 return win32_error("DuplicateHandle", NULL);
4193
4194 /* Close the inheritable version of ChildStdin
4195 that we're using. */
4196 CloseHandle(hChildStdinWr);
4197
4198 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4199 return win32_error("CreatePipe", NULL);
4200
4201 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004202 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4203 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004204 if (!fSuccess)
4205 return win32_error("DuplicateHandle", NULL);
4206
4207 /* Close the inheritable version of ChildStdout
4208 that we're using. */
4209 CloseHandle(hChildStdoutRd);
4210
4211 if (n != POPEN_4) {
4212 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4213 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004214 fSuccess = DuplicateHandle(GetCurrentProcess(),
4215 hChildStderrRd,
4216 GetCurrentProcess(),
4217 &hChildStderrRdDup, 0,
4218 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004219 if (!fSuccess)
4220 return win32_error("DuplicateHandle", NULL);
4221 /* Close the inheritable version of ChildStdErr that we're using. */
4222 CloseHandle(hChildStderrRd);
4223 }
Tim Peters5aa91602002-01-30 05:46:57 +00004224
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004225 switch (n) {
4226 case POPEN_1:
4227 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4228 case _O_WRONLY | _O_TEXT:
4229 /* Case for writing to child Stdin in text mode. */
4230 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4231 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004232 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004233 PyFile_SetBufSize(f, 0);
4234 /* We don't care about these pipes anymore, so close them. */
4235 CloseHandle(hChildStdoutRdDup);
4236 CloseHandle(hChildStderrRdDup);
4237 break;
4238
4239 case _O_RDONLY | _O_TEXT:
4240 /* Case for reading from child Stdout in text mode. */
4241 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4242 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004243 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004244 PyFile_SetBufSize(f, 0);
4245 /* We don't care about these pipes anymore, so close them. */
4246 CloseHandle(hChildStdinWrDup);
4247 CloseHandle(hChildStderrRdDup);
4248 break;
4249
4250 case _O_RDONLY | _O_BINARY:
4251 /* Case for readinig from child Stdout in binary mode. */
4252 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4253 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004254 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004255 PyFile_SetBufSize(f, 0);
4256 /* We don't care about these pipes anymore, so close them. */
4257 CloseHandle(hChildStdinWrDup);
4258 CloseHandle(hChildStderrRdDup);
4259 break;
4260
4261 case _O_WRONLY | _O_BINARY:
4262 /* Case for writing to child Stdin in binary mode. */
4263 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4264 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004265 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004266 PyFile_SetBufSize(f, 0);
4267 /* We don't care about these pipes anymore, so close them. */
4268 CloseHandle(hChildStdoutRdDup);
4269 CloseHandle(hChildStderrRdDup);
4270 break;
4271 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004272 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004273 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004274
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004275 case POPEN_2:
4276 case POPEN_4:
4277 {
4278 char *m1, *m2;
4279 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004280
Tim Peters7dca21e2002-08-19 00:42:29 +00004281 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 m1 = "r";
4283 m2 = "w";
4284 } else {
4285 m1 = "rb";
4286 m2 = "wb";
4287 }
4288
4289 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4290 f1 = _fdopen(fd1, m2);
4291 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4292 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004293 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004294 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004295 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004296 PyFile_SetBufSize(p2, 0);
4297
4298 if (n != 4)
4299 CloseHandle(hChildStderrRdDup);
4300
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004301 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004302 Py_XDECREF(p1);
4303 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004304 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004305 break;
4306 }
Tim Peters5aa91602002-01-30 05:46:57 +00004307
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004308 case POPEN_3:
4309 {
4310 char *m1, *m2;
4311 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004312
Tim Peters7dca21e2002-08-19 00:42:29 +00004313 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004314 m1 = "r";
4315 m2 = "w";
4316 } else {
4317 m1 = "rb";
4318 m2 = "wb";
4319 }
4320
4321 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4322 f1 = _fdopen(fd1, m2);
4323 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4324 f2 = _fdopen(fd2, m1);
4325 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4326 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004327 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004328 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4329 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004330 PyFile_SetBufSize(p1, 0);
4331 PyFile_SetBufSize(p2, 0);
4332 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004333 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004334 Py_XDECREF(p1);
4335 Py_XDECREF(p2);
4336 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004337 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 break;
4339 }
4340 }
4341
4342 if (n == POPEN_4) {
4343 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004344 hChildStdinRd,
4345 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004346 hChildStdoutWr,
4347 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004348 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004349 }
4350 else {
4351 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004352 hChildStdinRd,
4353 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004354 hChildStderrWr,
4355 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004356 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004357 }
4358
Mark Hammondb37a3732000-08-14 04:47:33 +00004359 /*
4360 * Insert the files we've created into the process dictionary
4361 * all referencing the list with the process handle and the
4362 * initial number of files (see description below in _PyPclose).
4363 * Since if _PyPclose later tried to wait on a process when all
4364 * handles weren't closed, it could create a deadlock with the
4365 * child, we spend some energy here to try to ensure that we
4366 * either insert all file handles into the dictionary or none
4367 * at all. It's a little clumsy with the various popen modes
4368 * and variable number of files involved.
4369 */
4370 if (!_PyPopenProcs) {
4371 _PyPopenProcs = PyDict_New();
4372 }
4373
4374 if (_PyPopenProcs) {
4375 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4376 int ins_rc[3];
4377
4378 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4379 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4380
4381 procObj = PyList_New(2);
4382 hProcessObj = PyLong_FromVoidPtr(hProcess);
4383 intObj = PyInt_FromLong(file_count);
4384
4385 if (procObj && hProcessObj && intObj) {
4386 PyList_SetItem(procObj,0,hProcessObj);
4387 PyList_SetItem(procObj,1,intObj);
4388
4389 fileObj[0] = PyLong_FromVoidPtr(f1);
4390 if (fileObj[0]) {
4391 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4392 fileObj[0],
4393 procObj);
4394 }
4395 if (file_count >= 2) {
4396 fileObj[1] = PyLong_FromVoidPtr(f2);
4397 if (fileObj[1]) {
4398 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4399 fileObj[1],
4400 procObj);
4401 }
4402 }
4403 if (file_count >= 3) {
4404 fileObj[2] = PyLong_FromVoidPtr(f3);
4405 if (fileObj[2]) {
4406 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4407 fileObj[2],
4408 procObj);
4409 }
4410 }
4411
4412 if (ins_rc[0] < 0 || !fileObj[0] ||
4413 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4414 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4415 /* Something failed - remove any dictionary
4416 * entries that did make it.
4417 */
4418 if (!ins_rc[0] && fileObj[0]) {
4419 PyDict_DelItem(_PyPopenProcs,
4420 fileObj[0]);
4421 }
4422 if (!ins_rc[1] && fileObj[1]) {
4423 PyDict_DelItem(_PyPopenProcs,
4424 fileObj[1]);
4425 }
4426 if (!ins_rc[2] && fileObj[2]) {
4427 PyDict_DelItem(_PyPopenProcs,
4428 fileObj[2]);
4429 }
4430 }
4431 }
Tim Peters5aa91602002-01-30 05:46:57 +00004432
Mark Hammondb37a3732000-08-14 04:47:33 +00004433 /*
4434 * Clean up our localized references for the dictionary keys
4435 * and value since PyDict_SetItem will Py_INCREF any copies
4436 * that got placed in the dictionary.
4437 */
4438 Py_XDECREF(procObj);
4439 Py_XDECREF(fileObj[0]);
4440 Py_XDECREF(fileObj[1]);
4441 Py_XDECREF(fileObj[2]);
4442 }
4443
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004444 /* Child is launched. Close the parents copy of those pipe
4445 * handles that only the child should have open. You need to
4446 * make sure that no handles to the write end of the output pipe
4447 * are maintained in this process or else the pipe will not close
4448 * when the child process exits and the ReadFile will hang. */
4449
4450 if (!CloseHandle(hChildStdinRd))
4451 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004452
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004453 if (!CloseHandle(hChildStdoutWr))
4454 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004455
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004456 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4457 return win32_error("CloseHandle", NULL);
4458
4459 return f;
4460}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004461
4462/*
4463 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4464 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004465 *
4466 * This function uses the _PyPopenProcs dictionary in order to map the
4467 * input file pointer to information about the process that was
4468 * originally created by the popen* call that created the file pointer.
4469 * The dictionary uses the file pointer as a key (with one entry
4470 * inserted for each file returned by the original popen* call) and a
4471 * single list object as the value for all files from a single call.
4472 * The list object contains the Win32 process handle at [0], and a file
4473 * count at [1], which is initialized to the total number of file
4474 * handles using that list.
4475 *
4476 * This function closes whichever handle it is passed, and decrements
4477 * the file count in the dictionary for the process handle pointed to
4478 * by this file. On the last close (when the file count reaches zero),
4479 * this function will wait for the child process and then return its
4480 * exit code as the result of the close() operation. This permits the
4481 * files to be closed in any order - it is always the close() of the
4482 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004483 */
Tim Peters736aa322000-09-01 06:51:24 +00004484
4485 /* RED_FLAG 31-Aug-2000 Tim
4486 * This is always called (today!) between a pair of
4487 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4488 * macros. So the thread running this has no valid thread state, as
4489 * far as Python is concerned. However, this calls some Python API
4490 * functions that cannot be called safely without a valid thread
4491 * state, in particular PyDict_GetItem.
4492 * As a temporary hack (although it may last for years ...), we
4493 * *rely* on not having a valid thread state in this function, in
4494 * order to create our own "from scratch".
4495 * This will deadlock if _PyPclose is ever called by a thread
4496 * holding the global lock.
4497 */
4498
Fredrik Lundh56055a42000-07-23 19:47:12 +00004499static int _PyPclose(FILE *file)
4500{
Fredrik Lundh20318932000-07-26 17:29:12 +00004501 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004502 DWORD exit_code;
4503 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004504 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4505 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004506#ifdef WITH_THREAD
4507 PyInterpreterState* pInterpreterState;
4508 PyThreadState* pThreadState;
4509#endif
4510
Fredrik Lundh20318932000-07-26 17:29:12 +00004511 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004512 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004513 */
4514 result = fclose(file);
4515
Tim Peters736aa322000-09-01 06:51:24 +00004516#ifdef WITH_THREAD
4517 /* Bootstrap a valid thread state into existence. */
4518 pInterpreterState = PyInterpreterState_New();
4519 if (!pInterpreterState) {
4520 /* Well, we're hosed now! We don't have a thread
4521 * state, so can't call a nice error routine, or raise
4522 * an exception. Just die.
4523 */
4524 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004525 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004526 return -1; /* unreachable */
4527 }
4528 pThreadState = PyThreadState_New(pInterpreterState);
4529 if (!pThreadState) {
4530 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004531 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004532 return -1; /* unreachable */
4533 }
4534 /* Grab the global lock. Note that this will deadlock if the
4535 * current thread already has the lock! (see RED_FLAG comments
4536 * before this function)
4537 */
4538 PyEval_RestoreThread(pThreadState);
4539#endif
4540
Fredrik Lundh56055a42000-07-23 19:47:12 +00004541 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004542 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4543 (procObj = PyDict_GetItem(_PyPopenProcs,
4544 fileObj)) != NULL &&
4545 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4546 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4547
4548 hProcess = PyLong_AsVoidPtr(hProcessObj);
4549 file_count = PyInt_AsLong(intObj);
4550
4551 if (file_count > 1) {
4552 /* Still other files referencing process */
4553 file_count--;
4554 PyList_SetItem(procObj,1,
4555 PyInt_FromLong(file_count));
4556 } else {
4557 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004558 if (result != EOF &&
4559 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4560 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004561 /* Possible truncation here in 16-bit environments, but
4562 * real exit codes are just the lower byte in any event.
4563 */
4564 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004565 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004566 /* Indicate failure - this will cause the file object
4567 * to raise an I/O error and translate the last Win32
4568 * error code from errno. We do have a problem with
4569 * last errors that overlap the normal errno table,
4570 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004571 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004572 if (result != EOF) {
4573 /* If the error wasn't from the fclose(), then
4574 * set errno for the file object error handling.
4575 */
4576 errno = GetLastError();
4577 }
4578 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004579 }
4580
4581 /* Free up the native handle at this point */
4582 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004583 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004584
Mark Hammondb37a3732000-08-14 04:47:33 +00004585 /* Remove this file pointer from dictionary */
4586 PyDict_DelItem(_PyPopenProcs, fileObj);
4587
4588 if (PyDict_Size(_PyPopenProcs) == 0) {
4589 Py_DECREF(_PyPopenProcs);
4590 _PyPopenProcs = NULL;
4591 }
4592
4593 } /* if object retrieval ok */
4594
4595 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004596 } /* if _PyPopenProcs */
4597
Tim Peters736aa322000-09-01 06:51:24 +00004598#ifdef WITH_THREAD
4599 /* Tear down the thread & interpreter states.
4600 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004601 * call the thread clear & delete functions, and indeed insist on
4602 * doing that themselves. The lock must be held during the clear, but
4603 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004604 */
4605 PyInterpreterState_Clear(pInterpreterState);
4606 PyEval_ReleaseThread(pThreadState);
4607 PyInterpreterState_Delete(pInterpreterState);
4608#endif
4609
Fredrik Lundh56055a42000-07-23 19:47:12 +00004610 return result;
4611}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004612
4613#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004615posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004616{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004617 char *name;
4618 char *mode = "r";
4619 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004620 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004621 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004622 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004623 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004624 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004625 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004626 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004627 if (fp == NULL)
4628 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004629 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004630 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004632 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004633}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004634
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004636#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638
Guido van Rossumb6775db1994-08-01 11:34:53 +00004639#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004641"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642Set the current process's user id.");
4643
Barry Warsaw53699e91996-12-10 23:23:01 +00004644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004646{
4647 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004648 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004649 return NULL;
4650 if (setuid(uid) < 0)
4651 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004652 Py_INCREF(Py_None);
4653 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004654}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004655#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004657
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004658#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004660"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661Set the current process's effective user id.");
4662
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004663static PyObject *
4664posix_seteuid (PyObject *self, PyObject *args)
4665{
4666 int euid;
4667 if (!PyArg_ParseTuple(args, "i", &euid)) {
4668 return NULL;
4669 } else if (seteuid(euid) < 0) {
4670 return posix_error();
4671 } else {
4672 Py_INCREF(Py_None);
4673 return Py_None;
4674 }
4675}
4676#endif /* HAVE_SETEUID */
4677
4678#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004679PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004680"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681Set the current process's effective group id.");
4682
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004683static PyObject *
4684posix_setegid (PyObject *self, PyObject *args)
4685{
4686 int egid;
4687 if (!PyArg_ParseTuple(args, "i", &egid)) {
4688 return NULL;
4689 } else if (setegid(egid) < 0) {
4690 return posix_error();
4691 } else {
4692 Py_INCREF(Py_None);
4693 return Py_None;
4694 }
4695}
4696#endif /* HAVE_SETEGID */
4697
4698#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004700"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701Set the current process's real and effective user ids.");
4702
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004703static PyObject *
4704posix_setreuid (PyObject *self, PyObject *args)
4705{
4706 int ruid, euid;
4707 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4708 return NULL;
4709 } else if (setreuid(ruid, euid) < 0) {
4710 return posix_error();
4711 } else {
4712 Py_INCREF(Py_None);
4713 return Py_None;
4714 }
4715}
4716#endif /* HAVE_SETREUID */
4717
4718#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Set the current process's real and effective group ids.");
4722
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004723static PyObject *
4724posix_setregid (PyObject *self, PyObject *args)
4725{
4726 int rgid, egid;
4727 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4728 return NULL;
4729 } else if (setregid(rgid, egid) < 0) {
4730 return posix_error();
4731 } else {
4732 Py_INCREF(Py_None);
4733 return Py_None;
4734 }
4735}
4736#endif /* HAVE_SETREGID */
4737
Guido van Rossumb6775db1994-08-01 11:34:53 +00004738#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004740"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004742
Barry Warsaw53699e91996-12-10 23:23:01 +00004743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004744posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004745{
4746 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004747 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004748 return NULL;
4749 if (setgid(gid) < 0)
4750 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004751 Py_INCREF(Py_None);
4752 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004753}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004754#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004755
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004756#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004758"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004760
4761static PyObject *
4762posix_setgroups(PyObject *self, PyObject *args)
4763{
4764 PyObject *groups;
4765 int i, len;
4766 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004767
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004768 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4769 return NULL;
4770 if (!PySequence_Check(groups)) {
4771 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4772 return NULL;
4773 }
4774 len = PySequence_Size(groups);
4775 if (len > MAX_GROUPS) {
4776 PyErr_SetString(PyExc_ValueError, "too many groups");
4777 return NULL;
4778 }
4779 for(i = 0; i < len; i++) {
4780 PyObject *elem;
4781 elem = PySequence_GetItem(groups, i);
4782 if (!elem)
4783 return NULL;
4784 if (!PyInt_Check(elem)) {
4785 PyErr_SetString(PyExc_TypeError,
4786 "groups must be integers");
4787 Py_DECREF(elem);
4788 return NULL;
4789 }
4790 /* XXX: check that value fits into gid_t. */
4791 grouplist[i] = PyInt_AsLong(elem);
4792 Py_DECREF(elem);
4793 }
4794
4795 if (setgroups(len, grouplist) < 0)
4796 return posix_error();
4797 Py_INCREF(Py_None);
4798 return Py_None;
4799}
4800#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004801
Guido van Rossumb6775db1994-08-01 11:34:53 +00004802#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004803PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004804"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004805Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004806
Barry Warsaw53699e91996-12-10 23:23:01 +00004807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004808posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004809{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004810 int pid, options;
4811#ifdef UNION_WAIT
4812 union wait status;
4813#define status_i (status.w_status)
4814#else
4815 int status;
4816#define status_i status
4817#endif
4818 status_i = 0;
4819
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004820 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004821 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004822 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004823 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004824 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004825 if (pid == -1)
4826 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004827 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004828 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004829}
4830
Tim Petersab034fa2002-02-01 11:27:43 +00004831#elif defined(HAVE_CWAIT)
4832
4833/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004834PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004835"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004836"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004837
4838static PyObject *
4839posix_waitpid(PyObject *self, PyObject *args)
4840{
4841 int pid, options;
4842 int status;
4843
4844 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4845 return NULL;
4846 Py_BEGIN_ALLOW_THREADS
4847 pid = _cwait(&status, pid, options);
4848 Py_END_ALLOW_THREADS
4849 if (pid == -1)
4850 return posix_error();
4851 else
4852 /* shift the status left a byte so this is more like the
4853 POSIX waitpid */
4854 return Py_BuildValue("ii", pid, status << 8);
4855}
4856#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004857
Guido van Rossumad0ee831995-03-01 10:34:45 +00004858#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004859PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004860"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004861Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004862
Barry Warsaw53699e91996-12-10 23:23:01 +00004863static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004864posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004865{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004866 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004867#ifdef UNION_WAIT
4868 union wait status;
4869#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004870#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004871 int status;
4872#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004873#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004874
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004875 status_i = 0;
4876 Py_BEGIN_ALLOW_THREADS
4877 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004879 if (pid == -1)
4880 return posix_error();
4881 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004882 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004883#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004884}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004885#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004887
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004888PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004889"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004890Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004891
Barry Warsaw53699e91996-12-10 23:23:01 +00004892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004893posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004894{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004895#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004896 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004897#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004898#ifdef MS_WINDOWS
4899 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4900#else
4901 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4902#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004903#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004904}
4905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004906
Guido van Rossumb6775db1994-08-01 11:34:53 +00004907#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004909"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004910Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Barry Warsaw53699e91996-12-10 23:23:01 +00004912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004913posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004914{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004915 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004916 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004917 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004918 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004919 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004920 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004921 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004922 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004923 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004924 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004925 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004927#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Guido van Rossumb6775db1994-08-01 11:34:53 +00004930#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004932"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004933Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004934
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004936posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004937{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004938 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004939}
4940#endif /* HAVE_SYMLINK */
4941
4942
4943#ifdef HAVE_TIMES
4944#ifndef HZ
4945#define HZ 60 /* Universal constant :-) */
4946#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004947
Guido van Rossumd48f2521997-12-05 22:19:34 +00004948#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4949static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004950system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004951{
4952 ULONG value = 0;
4953
4954 Py_BEGIN_ALLOW_THREADS
4955 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4956 Py_END_ALLOW_THREADS
4957
4958 return value;
4959}
4960
4961static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004962posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004963{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004964 /* Currently Only Uptime is Provided -- Others Later */
4965 return Py_BuildValue("ddddd",
4966 (double)0 /* t.tms_utime / HZ */,
4967 (double)0 /* t.tms_stime / HZ */,
4968 (double)0 /* t.tms_cutime / HZ */,
4969 (double)0 /* t.tms_cstime / HZ */,
4970 (double)system_uptime() / 1000);
4971}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004972#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004974posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004975{
4976 struct tms t;
4977 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004978 errno = 0;
4979 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004980 if (c == (clock_t) -1)
4981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004982 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004983 (double)t.tms_utime / HZ,
4984 (double)t.tms_stime / HZ,
4985 (double)t.tms_cutime / HZ,
4986 (double)t.tms_cstime / HZ,
4987 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004988}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004989#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004990#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004991
4992
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004993#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004994#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004995static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004996posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004997{
4998 FILETIME create, exit, kernel, user;
4999 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005000 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005001 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5002 /* The fields of a FILETIME structure are the hi and lo part
5003 of a 64-bit value expressed in 100 nanosecond units.
5004 1e7 is one second in such units; 1e-7 the inverse.
5005 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5006 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005007 return Py_BuildValue(
5008 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005009 (double)(kernel.dwHighDateTime*429.4967296 +
5010 kernel.dwLowDateTime*1e-7),
5011 (double)(user.dwHighDateTime*429.4967296 +
5012 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005013 (double)0,
5014 (double)0,
5015 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005016}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005017#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005018
5019#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005020PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005021"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005022Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005023#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005025
Guido van Rossumb6775db1994-08-01 11:34:53 +00005026#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005027PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005028"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005029Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005030
Barry Warsaw53699e91996-12-10 23:23:01 +00005031static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005032posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005033{
Guido van Rossum687dd131993-05-17 08:34:16 +00005034 if (setsid() < 0)
5035 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005036 Py_INCREF(Py_None);
5037 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005038}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005039#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005040
Guido van Rossumb6775db1994-08-01 11:34:53 +00005041#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005042PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005043"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005045
Barry Warsaw53699e91996-12-10 23:23:01 +00005046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005047posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005048{
5049 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005050 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005051 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005052 if (setpgid(pid, pgrp) < 0)
5053 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 Py_INCREF(Py_None);
5055 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005056}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005057#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Guido van Rossumb6775db1994-08-01 11:34:53 +00005060#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005061PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005062"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005063Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005064
Barry Warsaw53699e91996-12-10 23:23:01 +00005065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005066posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005067{
5068 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005070 return NULL;
5071 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005072 if (pgid < 0)
5073 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005074 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005075}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005076#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Guido van Rossumb6775db1994-08-01 11:34:53 +00005079#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005081"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005082Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Barry Warsaw53699e91996-12-10 23:23:01 +00005084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005085posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005086{
5087 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005088 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005089 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005090 if (tcsetpgrp(fd, pgid) < 0)
5091 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005092 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005093 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005094}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005095#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005096
Guido van Rossum687dd131993-05-17 08:34:16 +00005097/* Functions acting on file descriptors */
5098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005099PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005100"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005102
Barry Warsaw53699e91996-12-10 23:23:01 +00005103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005104posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005105{
Mark Hammondef8b6542001-05-13 08:04:26 +00005106 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005107 int flag;
5108 int mode = 0777;
5109 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005110
5111#ifdef MS_WINDOWS
5112 if (unicode_file_names()) {
5113 PyUnicodeObject *po;
5114 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5115 Py_BEGIN_ALLOW_THREADS
5116 /* PyUnicode_AS_UNICODE OK without thread
5117 lock as it is a simple dereference. */
5118 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5119 Py_END_ALLOW_THREADS
5120 if (fd < 0)
5121 return posix_error();
5122 return PyInt_FromLong((long)fd);
5123 }
5124 /* Drop the argument parsing error as narrow strings
5125 are also valid. */
5126 PyErr_Clear();
5127 }
5128#endif
5129
Tim Peters5aa91602002-01-30 05:46:57 +00005130 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005131 Py_FileSystemDefaultEncoding, &file,
5132 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005133 return NULL;
5134
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005136 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005138 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005139 return posix_error_with_allocated_filename(file);
5140 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005141 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005142}
5143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005145PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005146"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005148
Barry Warsaw53699e91996-12-10 23:23:01 +00005149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005151{
5152 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005153 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005154 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005155 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005156 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005157 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005158 if (res < 0)
5159 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005160 Py_INCREF(Py_None);
5161 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005162}
5163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005165PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005166"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005168
Barry Warsaw53699e91996-12-10 23:23:01 +00005169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005170posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005171{
5172 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005174 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005175 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005176 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005177 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005178 if (fd < 0)
5179 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005180 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005181}
5182
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005184PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005185"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005187
Barry Warsaw53699e91996-12-10 23:23:01 +00005188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005189posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005190{
5191 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005192 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005193 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005194 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005195 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005196 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005197 if (res < 0)
5198 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005199 Py_INCREF(Py_None);
5200 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005201}
5202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005204PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005205"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005207
Barry Warsaw53699e91996-12-10 23:23:01 +00005208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005209posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005210{
5211 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005212#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005213 LONG_LONG pos, res;
5214#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005215 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005216#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005217 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005218 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005219 return NULL;
5220#ifdef SEEK_SET
5221 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5222 switch (how) {
5223 case 0: how = SEEK_SET; break;
5224 case 1: how = SEEK_CUR; break;
5225 case 2: how = SEEK_END; break;
5226 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005227#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005228
5229#if !defined(HAVE_LARGEFILE_SUPPORT)
5230 pos = PyInt_AsLong(posobj);
5231#else
5232 pos = PyLong_Check(posobj) ?
5233 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5234#endif
5235 if (PyErr_Occurred())
5236 return NULL;
5237
Barry Warsaw53699e91996-12-10 23:23:01 +00005238 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005239#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005240 res = _lseeki64(fd, pos, how);
5241#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005242 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005243#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005244 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005245 if (res < 0)
5246 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005247
5248#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005249 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005250#else
5251 return PyLong_FromLongLong(res);
5252#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005253}
5254
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005256PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005257"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005259
Barry Warsaw53699e91996-12-10 23:23:01 +00005260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005261posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005262{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005263 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005264 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005265 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005266 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005267 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005268 if (buffer == NULL)
5269 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005270 Py_BEGIN_ALLOW_THREADS
5271 n = read(fd, PyString_AsString(buffer), size);
5272 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005273 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005274 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005275 return posix_error();
5276 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005277 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005278 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005279 return buffer;
5280}
5281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005283PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005284"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005285Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005286
Barry Warsaw53699e91996-12-10 23:23:01 +00005287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005288posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005289{
5290 int fd, size;
5291 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005292 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005293 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005294 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005295 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005296 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005297 if (size < 0)
5298 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005299 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005300}
5301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005303PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005304"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005306
Barry Warsaw53699e91996-12-10 23:23:01 +00005307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005308posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005309{
5310 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005311 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005312 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005313 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005314 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005315 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005316 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005317 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005318 if (res != 0)
5319 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005320
Fred Drake699f3522000-06-29 21:12:41 +00005321 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005322}
5323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005326"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005327Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Barry Warsaw53699e91996-12-10 23:23:01 +00005329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005330posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005331{
Guido van Rossum687dd131993-05-17 08:34:16 +00005332 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005333 char *mode = "r";
5334 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005335 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005336 PyObject *f;
5337 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005338 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005339
Thomas Heller1f043e22002-11-07 16:00:59 +00005340 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5341 PyErr_Format(PyExc_ValueError,
5342 "invalid file mode '%s'", mode);
5343 return NULL;
5344 }
5345
Barry Warsaw53699e91996-12-10 23:23:01 +00005346 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005347 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005348 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005349 if (fp == NULL)
5350 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005351 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005352 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005353 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005354 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005355}
5356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005358"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005359Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005361
5362static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005363posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005364{
5365 int fd;
5366 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5367 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005368 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005369}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005370
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005371#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005373"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005375
Barry Warsaw53699e91996-12-10 23:23:01 +00005376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005377posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005378{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005379#if defined(PYOS_OS2)
5380 HFILE read, write;
5381 APIRET rc;
5382
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005383 Py_BEGIN_ALLOW_THREADS
5384 rc = DosCreatePipe( &read, &write, 4096);
5385 Py_END_ALLOW_THREADS
5386 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005387 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005388
5389 return Py_BuildValue("(ii)", read, write);
5390#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005391#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005392 int fds[2];
5393 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005394 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005395#if defined(__VMS)
5396 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5397#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005398 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005399#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005400 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005401 if (res != 0)
5402 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005403 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005404#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005405 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005406 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005407 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005408 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005409 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005410 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005411 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005412 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005413 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5414 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005415 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005416#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005417#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005418}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005419#endif /* HAVE_PIPE */
5420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005421
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005422#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005424"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005426
Barry Warsaw53699e91996-12-10 23:23:01 +00005427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005428posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005429{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005430 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005431 int mode = 0666;
5432 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005433 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005434 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005435 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005436 res = mkfifo(filename, mode);
5437 Py_END_ALLOW_THREADS
5438 if (res < 0)
5439 return posix_error();
5440 Py_INCREF(Py_None);
5441 return Py_None;
5442}
5443#endif
5444
5445
Neal Norwitz11690112002-07-30 01:08:28 +00005446#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005448"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005449Create a filesystem node (file, device special file or named pipe)\n\
5450named filename. mode specifies both the permissions to use and the\n\
5451type of node to be created, being combined (bitwise OR) with one of\n\
5452S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005453device defines the newly created device special file (probably using\n\
5454os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005455
5456
5457static PyObject *
5458posix_mknod(PyObject *self, PyObject *args)
5459{
5460 char *filename;
5461 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005462 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005463 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005464 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005465 return NULL;
5466 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005467 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005468 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005469 if (res < 0)
5470 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005471 Py_INCREF(Py_None);
5472 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005473}
5474#endif
5475
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005476#ifdef HAVE_DEVICE_MACROS
5477PyDoc_STRVAR(posix_major__doc__,
5478"major(device) -> major number\n\
5479Extracts a device major number from a raw device number.");
5480
5481static PyObject *
5482posix_major(PyObject *self, PyObject *args)
5483{
5484 int device;
5485 if (!PyArg_ParseTuple(args, "i:major", &device))
5486 return NULL;
5487 return PyInt_FromLong((long)major(device));
5488}
5489
5490PyDoc_STRVAR(posix_minor__doc__,
5491"minor(device) -> minor number\n\
5492Extracts a device minor number from a raw device number.");
5493
5494static PyObject *
5495posix_minor(PyObject *self, PyObject *args)
5496{
5497 int device;
5498 if (!PyArg_ParseTuple(args, "i:minor", &device))
5499 return NULL;
5500 return PyInt_FromLong((long)minor(device));
5501}
5502
5503PyDoc_STRVAR(posix_makedev__doc__,
5504"makedev(major, minor) -> device number\n\
5505Composes a raw device number from the major and minor device numbers.");
5506
5507static PyObject *
5508posix_makedev(PyObject *self, PyObject *args)
5509{
5510 int major, minor;
5511 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5512 return NULL;
5513 return PyInt_FromLong((long)makedev(major, minor));
5514}
5515#endif /* device macros */
5516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005517
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005518#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005522
Barry Warsaw53699e91996-12-10 23:23:01 +00005523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005524posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005525{
5526 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005527 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005528 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005529 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005530
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005531 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005532 return NULL;
5533
5534#if !defined(HAVE_LARGEFILE_SUPPORT)
5535 length = PyInt_AsLong(lenobj);
5536#else
5537 length = PyLong_Check(lenobj) ?
5538 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5539#endif
5540 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005541 return NULL;
5542
Barry Warsaw53699e91996-12-10 23:23:01 +00005543 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005544 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005545 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005546 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005547 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005548 return NULL;
5549 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005550 Py_INCREF(Py_None);
5551 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005552}
5553#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005554
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005555#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005556PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005557"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005558Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005559
Fred Drake762e2061999-08-26 17:23:54 +00005560/* Save putenv() parameters as values here, so we can collect them when they
5561 * get re-set with another call for the same key. */
5562static PyObject *posix_putenv_garbage;
5563
Tim Peters5aa91602002-01-30 05:46:57 +00005564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005565posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005566{
5567 char *s1, *s2;
5568 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005569 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005570 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005571
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005573 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005574
5575#if defined(PYOS_OS2)
5576 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5577 APIRET rc;
5578
5579 if (strlen(s2) == 0) /* If New Value is an Empty String */
5580 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5581
5582 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5583 if (rc != NO_ERROR)
5584 return os2_error(rc);
5585
5586 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5587 APIRET rc;
5588
5589 if (strlen(s2) == 0) /* If New Value is an Empty String */
5590 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5591
5592 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5593 if (rc != NO_ERROR)
5594 return os2_error(rc);
5595 } else {
5596#endif
5597
Fred Drake762e2061999-08-26 17:23:54 +00005598 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005599 len = strlen(s1) + strlen(s2) + 2;
5600 /* len includes space for a trailing \0; the size arg to
5601 PyString_FromStringAndSize does not count that */
5602 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005603 if (newstr == NULL)
5604 return PyErr_NoMemory();
5605 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005606 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005607 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005608 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005609 posix_error();
5610 return NULL;
5611 }
Fred Drake762e2061999-08-26 17:23:54 +00005612 /* Install the first arg and newstr in posix_putenv_garbage;
5613 * this will cause previous value to be collected. This has to
5614 * happen after the real putenv() call because the old value
5615 * was still accessible until then. */
5616 if (PyDict_SetItem(posix_putenv_garbage,
5617 PyTuple_GET_ITEM(args, 0), newstr)) {
5618 /* really not much we can do; just leak */
5619 PyErr_Clear();
5620 }
5621 else {
5622 Py_DECREF(newstr);
5623 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005624
5625#if defined(PYOS_OS2)
5626 }
5627#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005628 Py_INCREF(Py_None);
5629 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005630}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005631#endif /* putenv */
5632
Guido van Rossumc524d952001-10-19 01:31:59 +00005633#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005634PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005635"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005636Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005637
5638static PyObject *
5639posix_unsetenv(PyObject *self, PyObject *args)
5640{
5641 char *s1;
5642
5643 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5644 return NULL;
5645
5646 unsetenv(s1);
5647
5648 /* Remove the key from posix_putenv_garbage;
5649 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005650 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005651 * old value was still accessible until then.
5652 */
5653 if (PyDict_DelItem(posix_putenv_garbage,
5654 PyTuple_GET_ITEM(args, 0))) {
5655 /* really not much we can do; just leak */
5656 PyErr_Clear();
5657 }
5658
5659 Py_INCREF(Py_None);
5660 return Py_None;
5661}
5662#endif /* unsetenv */
5663
Guido van Rossumb6a47161997-09-15 22:54:34 +00005664#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005668
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005670posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005671{
5672 int code;
5673 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005674 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005675 return NULL;
5676 message = strerror(code);
5677 if (message == NULL) {
5678 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005679 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005680 return NULL;
5681 }
5682 return PyString_FromString(message);
5683}
5684#endif /* strerror */
5685
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005686
Guido van Rossumc9641791998-08-04 15:26:23 +00005687#ifdef HAVE_SYS_WAIT_H
5688
Fred Drake106c1a02002-04-23 15:58:02 +00005689#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005691"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005693
5694static PyObject *
5695posix_WCOREDUMP(PyObject *self, PyObject *args)
5696{
5697#ifdef UNION_WAIT
5698 union wait status;
5699#define status_i (status.w_status)
5700#else
5701 int status;
5702#define status_i status
5703#endif
5704 status_i = 0;
5705
5706 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5707 {
5708 return NULL;
5709 }
5710
5711 return PyBool_FromLong(WCOREDUMP(status));
5712#undef status_i
5713}
5714#endif /* WCOREDUMP */
5715
5716#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005718"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005719Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005721
5722static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005723posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005724{
5725#ifdef UNION_WAIT
5726 union wait status;
5727#define status_i (status.w_status)
5728#else
5729 int status;
5730#define status_i status
5731#endif
5732 status_i = 0;
5733
5734 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5735 {
5736 return NULL;
5737 }
5738
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005739 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005740#undef status_i
5741}
5742#endif /* WIFCONTINUED */
5743
Guido van Rossumc9641791998-08-04 15:26:23 +00005744#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005746"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005748
5749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005750posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005751{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005752#ifdef UNION_WAIT
5753 union wait status;
5754#define status_i (status.w_status)
5755#else
5756 int status;
5757#define status_i status
5758#endif
5759 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005760
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005761 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005762 {
5763 return NULL;
5764 }
Tim Peters5aa91602002-01-30 05:46:57 +00005765
Fred Drake106c1a02002-04-23 15:58:02 +00005766 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005767#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005768}
5769#endif /* WIFSTOPPED */
5770
5771#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005773"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005775
5776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005777posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005778{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005779#ifdef UNION_WAIT
5780 union wait status;
5781#define status_i (status.w_status)
5782#else
5783 int status;
5784#define status_i status
5785#endif
5786 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005787
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005788 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005789 {
5790 return NULL;
5791 }
Tim Peters5aa91602002-01-30 05:46:57 +00005792
Fred Drake106c1a02002-04-23 15:58:02 +00005793 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005794#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005795}
5796#endif /* WIFSIGNALED */
5797
5798#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005799PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005800"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005801Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005802system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005803
5804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005805posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005806{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005807#ifdef UNION_WAIT
5808 union wait status;
5809#define status_i (status.w_status)
5810#else
5811 int status;
5812#define status_i status
5813#endif
5814 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005815
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005816 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005817 {
5818 return NULL;
5819 }
Tim Peters5aa91602002-01-30 05:46:57 +00005820
Fred Drake106c1a02002-04-23 15:58:02 +00005821 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005822#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005823}
5824#endif /* WIFEXITED */
5825
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005826#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005827PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005828"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005829Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005830
5831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005832posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005833{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005834#ifdef UNION_WAIT
5835 union wait status;
5836#define status_i (status.w_status)
5837#else
5838 int status;
5839#define status_i status
5840#endif
5841 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005842
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005843 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005844 {
5845 return NULL;
5846 }
Tim Peters5aa91602002-01-30 05:46:57 +00005847
Guido van Rossumc9641791998-08-04 15:26:23 +00005848 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005849#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005850}
5851#endif /* WEXITSTATUS */
5852
5853#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005854PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005855"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005856Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005857value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005858
5859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005860posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005861{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005862#ifdef UNION_WAIT
5863 union wait status;
5864#define status_i (status.w_status)
5865#else
5866 int status;
5867#define status_i status
5868#endif
5869 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005870
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005871 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005872 {
5873 return NULL;
5874 }
Tim Peters5aa91602002-01-30 05:46:57 +00005875
Guido van Rossumc9641791998-08-04 15:26:23 +00005876 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005877#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005878}
5879#endif /* WTERMSIG */
5880
5881#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005882PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005883"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884Return the signal that stopped the process that provided\n\
5885the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005886
5887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005888posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005889{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005890#ifdef UNION_WAIT
5891 union wait status;
5892#define status_i (status.w_status)
5893#else
5894 int status;
5895#define status_i status
5896#endif
5897 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005898
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005899 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005900 {
5901 return NULL;
5902 }
Tim Peters5aa91602002-01-30 05:46:57 +00005903
Guido van Rossumc9641791998-08-04 15:26:23 +00005904 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005905#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005906}
5907#endif /* WSTOPSIG */
5908
5909#endif /* HAVE_SYS_WAIT_H */
5910
5911
Guido van Rossum94f6f721999-01-06 18:42:14 +00005912#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005913#ifdef _SCO_DS
5914/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5915 needed definitions in sys/statvfs.h */
5916#define _SVID3
5917#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005918#include <sys/statvfs.h>
5919
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005920static PyObject*
5921_pystatvfs_fromstructstatvfs(struct statvfs st) {
5922 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5923 if (v == NULL)
5924 return NULL;
5925
5926#if !defined(HAVE_LARGEFILE_SUPPORT)
5927 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5928 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5929 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5930 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5931 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5932 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5933 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5934 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5935 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5936 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5937#else
5938 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5939 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005940 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005941 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005942 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005943 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5944 PyStructSequence_SET_ITEM(v, 4,
5945 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005946 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005947 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005948 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005949 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005950 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005951 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5952 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5953 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5954#endif
5955
5956 return v;
5957}
5958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005959PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005960"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005962
5963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005964posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005965{
5966 int fd, res;
5967 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005968
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005969 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005970 return NULL;
5971 Py_BEGIN_ALLOW_THREADS
5972 res = fstatvfs(fd, &st);
5973 Py_END_ALLOW_THREADS
5974 if (res != 0)
5975 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005976
5977 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005978}
5979#endif /* HAVE_FSTATVFS */
5980
5981
5982#if defined(HAVE_STATVFS)
5983#include <sys/statvfs.h>
5984
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005986"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005988
5989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005990posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005991{
5992 char *path;
5993 int res;
5994 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005995 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005996 return NULL;
5997 Py_BEGIN_ALLOW_THREADS
5998 res = statvfs(path, &st);
5999 Py_END_ALLOW_THREADS
6000 if (res != 0)
6001 return posix_error_with_filename(path);
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_STATVFS */
6006
6007
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006008#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006009PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006010"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006011Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006012The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006014
6015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006017{
6018 PyObject *result = NULL;
6019 char *dir = NULL;
6020 char *pfx = NULL;
6021 char *name;
6022
6023 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6024 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006025
6026 if (PyErr_Warn(PyExc_RuntimeWarning,
6027 "tempnam is a potential security risk to your program") < 0)
6028 return NULL;
6029
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006030#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006031 name = _tempnam(dir, pfx);
6032#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006033 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006034#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006035 if (name == NULL)
6036 return PyErr_NoMemory();
6037 result = PyString_FromString(name);
6038 free(name);
6039 return result;
6040}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006041#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006042
6043
6044#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006045PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006046"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006048
6049static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006050posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006051{
6052 FILE *fp;
6053
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006054 fp = tmpfile();
6055 if (fp == NULL)
6056 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006057 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006058}
6059#endif
6060
6061
6062#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006064"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006066
6067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006068posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006069{
6070 char buffer[L_tmpnam];
6071 char *name;
6072
Skip Montanaro95618b52001-08-18 18:52:10 +00006073 if (PyErr_Warn(PyExc_RuntimeWarning,
6074 "tmpnam is a potential security risk to your program") < 0)
6075 return NULL;
6076
Greg Wardb48bc172000-03-01 21:51:56 +00006077#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006078 name = tmpnam_r(buffer);
6079#else
6080 name = tmpnam(buffer);
6081#endif
6082 if (name == NULL) {
6083 PyErr_SetObject(PyExc_OSError,
6084 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006085#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006086 "unexpected NULL from tmpnam_r"
6087#else
6088 "unexpected NULL from tmpnam"
6089#endif
6090 ));
6091 return NULL;
6092 }
6093 return PyString_FromString(buffer);
6094}
6095#endif
6096
6097
Fred Drakec9680921999-12-13 16:37:25 +00006098/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6099 * It maps strings representing configuration variable names to
6100 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006101 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006102 * rarely-used constants. There are three separate tables that use
6103 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006104 *
6105 * This code is always included, even if none of the interfaces that
6106 * need it are included. The #if hackery needed to avoid it would be
6107 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006108 */
6109struct constdef {
6110 char *name;
6111 long value;
6112};
6113
Fred Drake12c6e2d1999-12-14 21:25:03 +00006114static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006115conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6116 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006117{
6118 if (PyInt_Check(arg)) {
6119 *valuep = PyInt_AS_LONG(arg);
6120 return 1;
6121 }
6122 if (PyString_Check(arg)) {
6123 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006124 size_t lo = 0;
6125 size_t mid;
6126 size_t hi = tablesize;
6127 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006128 char *confname = PyString_AS_STRING(arg);
6129 while (lo < hi) {
6130 mid = (lo + hi) / 2;
6131 cmp = strcmp(confname, table[mid].name);
6132 if (cmp < 0)
6133 hi = mid;
6134 else if (cmp > 0)
6135 lo = mid + 1;
6136 else {
6137 *valuep = table[mid].value;
6138 return 1;
6139 }
6140 }
6141 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6142 }
6143 else
6144 PyErr_SetString(PyExc_TypeError,
6145 "configuration names must be strings or integers");
6146 return 0;
6147}
6148
6149
6150#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6151static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006152#ifdef _PC_ABI_AIO_XFER_MAX
6153 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6154#endif
6155#ifdef _PC_ABI_ASYNC_IO
6156 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6157#endif
Fred Drakec9680921999-12-13 16:37:25 +00006158#ifdef _PC_ASYNC_IO
6159 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6160#endif
6161#ifdef _PC_CHOWN_RESTRICTED
6162 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6163#endif
6164#ifdef _PC_FILESIZEBITS
6165 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6166#endif
6167#ifdef _PC_LAST
6168 {"PC_LAST", _PC_LAST},
6169#endif
6170#ifdef _PC_LINK_MAX
6171 {"PC_LINK_MAX", _PC_LINK_MAX},
6172#endif
6173#ifdef _PC_MAX_CANON
6174 {"PC_MAX_CANON", _PC_MAX_CANON},
6175#endif
6176#ifdef _PC_MAX_INPUT
6177 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6178#endif
6179#ifdef _PC_NAME_MAX
6180 {"PC_NAME_MAX", _PC_NAME_MAX},
6181#endif
6182#ifdef _PC_NO_TRUNC
6183 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6184#endif
6185#ifdef _PC_PATH_MAX
6186 {"PC_PATH_MAX", _PC_PATH_MAX},
6187#endif
6188#ifdef _PC_PIPE_BUF
6189 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6190#endif
6191#ifdef _PC_PRIO_IO
6192 {"PC_PRIO_IO", _PC_PRIO_IO},
6193#endif
6194#ifdef _PC_SOCK_MAXBUF
6195 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6196#endif
6197#ifdef _PC_SYNC_IO
6198 {"PC_SYNC_IO", _PC_SYNC_IO},
6199#endif
6200#ifdef _PC_VDISABLE
6201 {"PC_VDISABLE", _PC_VDISABLE},
6202#endif
6203};
6204
Fred Drakec9680921999-12-13 16:37:25 +00006205static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006206conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006207{
6208 return conv_confname(arg, valuep, posix_constants_pathconf,
6209 sizeof(posix_constants_pathconf)
6210 / sizeof(struct constdef));
6211}
6212#endif
6213
6214#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006216"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006217Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006219
6220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006221posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006222{
6223 PyObject *result = NULL;
6224 int name, fd;
6225
Fred Drake12c6e2d1999-12-14 21:25:03 +00006226 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6227 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006228 long limit;
6229
6230 errno = 0;
6231 limit = fpathconf(fd, name);
6232 if (limit == -1 && errno != 0)
6233 posix_error();
6234 else
6235 result = PyInt_FromLong(limit);
6236 }
6237 return result;
6238}
6239#endif
6240
6241
6242#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006243PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006244"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006245Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006247
6248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006249posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006250{
6251 PyObject *result = NULL;
6252 int name;
6253 char *path;
6254
6255 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6256 conv_path_confname, &name)) {
6257 long limit;
6258
6259 errno = 0;
6260 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006261 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006262 if (errno == EINVAL)
6263 /* could be a path or name problem */
6264 posix_error();
6265 else
6266 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006267 }
Fred Drakec9680921999-12-13 16:37:25 +00006268 else
6269 result = PyInt_FromLong(limit);
6270 }
6271 return result;
6272}
6273#endif
6274
6275#ifdef HAVE_CONFSTR
6276static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006277#ifdef _CS_ARCHITECTURE
6278 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6279#endif
6280#ifdef _CS_HOSTNAME
6281 {"CS_HOSTNAME", _CS_HOSTNAME},
6282#endif
6283#ifdef _CS_HW_PROVIDER
6284 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6285#endif
6286#ifdef _CS_HW_SERIAL
6287 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6288#endif
6289#ifdef _CS_INITTAB_NAME
6290 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6291#endif
Fred Drakec9680921999-12-13 16:37:25 +00006292#ifdef _CS_LFS64_CFLAGS
6293 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6294#endif
6295#ifdef _CS_LFS64_LDFLAGS
6296 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6297#endif
6298#ifdef _CS_LFS64_LIBS
6299 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6300#endif
6301#ifdef _CS_LFS64_LINTFLAGS
6302 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6303#endif
6304#ifdef _CS_LFS_CFLAGS
6305 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6306#endif
6307#ifdef _CS_LFS_LDFLAGS
6308 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6309#endif
6310#ifdef _CS_LFS_LIBS
6311 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6312#endif
6313#ifdef _CS_LFS_LINTFLAGS
6314 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6315#endif
Fred Draked86ed291999-12-15 15:34:33 +00006316#ifdef _CS_MACHINE
6317 {"CS_MACHINE", _CS_MACHINE},
6318#endif
Fred Drakec9680921999-12-13 16:37:25 +00006319#ifdef _CS_PATH
6320 {"CS_PATH", _CS_PATH},
6321#endif
Fred Draked86ed291999-12-15 15:34:33 +00006322#ifdef _CS_RELEASE
6323 {"CS_RELEASE", _CS_RELEASE},
6324#endif
6325#ifdef _CS_SRPC_DOMAIN
6326 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6327#endif
6328#ifdef _CS_SYSNAME
6329 {"CS_SYSNAME", _CS_SYSNAME},
6330#endif
6331#ifdef _CS_VERSION
6332 {"CS_VERSION", _CS_VERSION},
6333#endif
Fred Drakec9680921999-12-13 16:37:25 +00006334#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6335 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6336#endif
6337#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6338 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6339#endif
6340#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6341 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6342#endif
6343#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6344 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6345#endif
6346#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6347 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6348#endif
6349#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6350 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6351#endif
6352#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6353 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6354#endif
6355#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6356 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6357#endif
6358#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6359 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6360#endif
6361#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6362 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6363#endif
6364#ifdef _CS_XBS5_LP64_OFF64_LIBS
6365 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6366#endif
6367#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6368 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6369#endif
6370#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6371 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6372#endif
6373#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6374 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6375#endif
6376#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6377 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6378#endif
6379#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6380 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6381#endif
Fred Draked86ed291999-12-15 15:34:33 +00006382#ifdef _MIPS_CS_AVAIL_PROCESSORS
6383 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6384#endif
6385#ifdef _MIPS_CS_BASE
6386 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6387#endif
6388#ifdef _MIPS_CS_HOSTID
6389 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6390#endif
6391#ifdef _MIPS_CS_HW_NAME
6392 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6393#endif
6394#ifdef _MIPS_CS_NUM_PROCESSORS
6395 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6396#endif
6397#ifdef _MIPS_CS_OSREL_MAJ
6398 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6399#endif
6400#ifdef _MIPS_CS_OSREL_MIN
6401 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6402#endif
6403#ifdef _MIPS_CS_OSREL_PATCH
6404 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6405#endif
6406#ifdef _MIPS_CS_OS_NAME
6407 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6408#endif
6409#ifdef _MIPS_CS_OS_PROVIDER
6410 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6411#endif
6412#ifdef _MIPS_CS_PROCESSORS
6413 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6414#endif
6415#ifdef _MIPS_CS_SERIAL
6416 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6417#endif
6418#ifdef _MIPS_CS_VENDOR
6419 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6420#endif
Fred Drakec9680921999-12-13 16:37:25 +00006421};
6422
6423static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006424conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006425{
6426 return conv_confname(arg, valuep, posix_constants_confstr,
6427 sizeof(posix_constants_confstr)
6428 / sizeof(struct constdef));
6429}
6430
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006432"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006433Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006434
6435static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006436posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006437{
6438 PyObject *result = NULL;
6439 int name;
6440 char buffer[64];
6441
6442 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6443 int len = confstr(name, buffer, sizeof(buffer));
6444
Fred Drakec9680921999-12-13 16:37:25 +00006445 errno = 0;
6446 if (len == 0) {
6447 if (errno != 0)
6448 posix_error();
6449 else
6450 result = PyString_FromString("");
6451 }
6452 else {
6453 if (len >= sizeof(buffer)) {
6454 result = PyString_FromStringAndSize(NULL, len);
6455 if (result != NULL)
6456 confstr(name, PyString_AS_STRING(result), len+1);
6457 }
6458 else
6459 result = PyString_FromString(buffer);
6460 }
6461 }
6462 return result;
6463}
6464#endif
6465
6466
6467#ifdef HAVE_SYSCONF
6468static struct constdef posix_constants_sysconf[] = {
6469#ifdef _SC_2_CHAR_TERM
6470 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6471#endif
6472#ifdef _SC_2_C_BIND
6473 {"SC_2_C_BIND", _SC_2_C_BIND},
6474#endif
6475#ifdef _SC_2_C_DEV
6476 {"SC_2_C_DEV", _SC_2_C_DEV},
6477#endif
6478#ifdef _SC_2_C_VERSION
6479 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6480#endif
6481#ifdef _SC_2_FORT_DEV
6482 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6483#endif
6484#ifdef _SC_2_FORT_RUN
6485 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6486#endif
6487#ifdef _SC_2_LOCALEDEF
6488 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6489#endif
6490#ifdef _SC_2_SW_DEV
6491 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6492#endif
6493#ifdef _SC_2_UPE
6494 {"SC_2_UPE", _SC_2_UPE},
6495#endif
6496#ifdef _SC_2_VERSION
6497 {"SC_2_VERSION", _SC_2_VERSION},
6498#endif
Fred Draked86ed291999-12-15 15:34:33 +00006499#ifdef _SC_ABI_ASYNCHRONOUS_IO
6500 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6501#endif
6502#ifdef _SC_ACL
6503 {"SC_ACL", _SC_ACL},
6504#endif
Fred Drakec9680921999-12-13 16:37:25 +00006505#ifdef _SC_AIO_LISTIO_MAX
6506 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6507#endif
Fred Drakec9680921999-12-13 16:37:25 +00006508#ifdef _SC_AIO_MAX
6509 {"SC_AIO_MAX", _SC_AIO_MAX},
6510#endif
6511#ifdef _SC_AIO_PRIO_DELTA_MAX
6512 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6513#endif
6514#ifdef _SC_ARG_MAX
6515 {"SC_ARG_MAX", _SC_ARG_MAX},
6516#endif
6517#ifdef _SC_ASYNCHRONOUS_IO
6518 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6519#endif
6520#ifdef _SC_ATEXIT_MAX
6521 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6522#endif
Fred Draked86ed291999-12-15 15:34:33 +00006523#ifdef _SC_AUDIT
6524 {"SC_AUDIT", _SC_AUDIT},
6525#endif
Fred Drakec9680921999-12-13 16:37:25 +00006526#ifdef _SC_AVPHYS_PAGES
6527 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6528#endif
6529#ifdef _SC_BC_BASE_MAX
6530 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6531#endif
6532#ifdef _SC_BC_DIM_MAX
6533 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6534#endif
6535#ifdef _SC_BC_SCALE_MAX
6536 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6537#endif
6538#ifdef _SC_BC_STRING_MAX
6539 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6540#endif
Fred Draked86ed291999-12-15 15:34:33 +00006541#ifdef _SC_CAP
6542 {"SC_CAP", _SC_CAP},
6543#endif
Fred Drakec9680921999-12-13 16:37:25 +00006544#ifdef _SC_CHARCLASS_NAME_MAX
6545 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6546#endif
6547#ifdef _SC_CHAR_BIT
6548 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6549#endif
6550#ifdef _SC_CHAR_MAX
6551 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6552#endif
6553#ifdef _SC_CHAR_MIN
6554 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6555#endif
6556#ifdef _SC_CHILD_MAX
6557 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6558#endif
6559#ifdef _SC_CLK_TCK
6560 {"SC_CLK_TCK", _SC_CLK_TCK},
6561#endif
6562#ifdef _SC_COHER_BLKSZ
6563 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6564#endif
6565#ifdef _SC_COLL_WEIGHTS_MAX
6566 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6567#endif
6568#ifdef _SC_DCACHE_ASSOC
6569 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6570#endif
6571#ifdef _SC_DCACHE_BLKSZ
6572 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6573#endif
6574#ifdef _SC_DCACHE_LINESZ
6575 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6576#endif
6577#ifdef _SC_DCACHE_SZ
6578 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6579#endif
6580#ifdef _SC_DCACHE_TBLKSZ
6581 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6582#endif
6583#ifdef _SC_DELAYTIMER_MAX
6584 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6585#endif
6586#ifdef _SC_EQUIV_CLASS_MAX
6587 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6588#endif
6589#ifdef _SC_EXPR_NEST_MAX
6590 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6591#endif
6592#ifdef _SC_FSYNC
6593 {"SC_FSYNC", _SC_FSYNC},
6594#endif
6595#ifdef _SC_GETGR_R_SIZE_MAX
6596 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6597#endif
6598#ifdef _SC_GETPW_R_SIZE_MAX
6599 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6600#endif
6601#ifdef _SC_ICACHE_ASSOC
6602 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6603#endif
6604#ifdef _SC_ICACHE_BLKSZ
6605 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6606#endif
6607#ifdef _SC_ICACHE_LINESZ
6608 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6609#endif
6610#ifdef _SC_ICACHE_SZ
6611 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6612#endif
Fred Draked86ed291999-12-15 15:34:33 +00006613#ifdef _SC_INF
6614 {"SC_INF", _SC_INF},
6615#endif
Fred Drakec9680921999-12-13 16:37:25 +00006616#ifdef _SC_INT_MAX
6617 {"SC_INT_MAX", _SC_INT_MAX},
6618#endif
6619#ifdef _SC_INT_MIN
6620 {"SC_INT_MIN", _SC_INT_MIN},
6621#endif
6622#ifdef _SC_IOV_MAX
6623 {"SC_IOV_MAX", _SC_IOV_MAX},
6624#endif
Fred Draked86ed291999-12-15 15:34:33 +00006625#ifdef _SC_IP_SECOPTS
6626 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6627#endif
Fred Drakec9680921999-12-13 16:37:25 +00006628#ifdef _SC_JOB_CONTROL
6629 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6630#endif
Fred Draked86ed291999-12-15 15:34:33 +00006631#ifdef _SC_KERN_POINTERS
6632 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6633#endif
6634#ifdef _SC_KERN_SIM
6635 {"SC_KERN_SIM", _SC_KERN_SIM},
6636#endif
Fred Drakec9680921999-12-13 16:37:25 +00006637#ifdef _SC_LINE_MAX
6638 {"SC_LINE_MAX", _SC_LINE_MAX},
6639#endif
6640#ifdef _SC_LOGIN_NAME_MAX
6641 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6642#endif
6643#ifdef _SC_LOGNAME_MAX
6644 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6645#endif
6646#ifdef _SC_LONG_BIT
6647 {"SC_LONG_BIT", _SC_LONG_BIT},
6648#endif
Fred Draked86ed291999-12-15 15:34:33 +00006649#ifdef _SC_MAC
6650 {"SC_MAC", _SC_MAC},
6651#endif
Fred Drakec9680921999-12-13 16:37:25 +00006652#ifdef _SC_MAPPED_FILES
6653 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6654#endif
6655#ifdef _SC_MAXPID
6656 {"SC_MAXPID", _SC_MAXPID},
6657#endif
6658#ifdef _SC_MB_LEN_MAX
6659 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6660#endif
6661#ifdef _SC_MEMLOCK
6662 {"SC_MEMLOCK", _SC_MEMLOCK},
6663#endif
6664#ifdef _SC_MEMLOCK_RANGE
6665 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6666#endif
6667#ifdef _SC_MEMORY_PROTECTION
6668 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6669#endif
6670#ifdef _SC_MESSAGE_PASSING
6671 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6672#endif
Fred Draked86ed291999-12-15 15:34:33 +00006673#ifdef _SC_MMAP_FIXED_ALIGNMENT
6674 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6675#endif
Fred Drakec9680921999-12-13 16:37:25 +00006676#ifdef _SC_MQ_OPEN_MAX
6677 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6678#endif
6679#ifdef _SC_MQ_PRIO_MAX
6680 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6681#endif
Fred Draked86ed291999-12-15 15:34:33 +00006682#ifdef _SC_NACLS_MAX
6683 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6684#endif
Fred Drakec9680921999-12-13 16:37:25 +00006685#ifdef _SC_NGROUPS_MAX
6686 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6687#endif
6688#ifdef _SC_NL_ARGMAX
6689 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6690#endif
6691#ifdef _SC_NL_LANGMAX
6692 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6693#endif
6694#ifdef _SC_NL_MSGMAX
6695 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6696#endif
6697#ifdef _SC_NL_NMAX
6698 {"SC_NL_NMAX", _SC_NL_NMAX},
6699#endif
6700#ifdef _SC_NL_SETMAX
6701 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6702#endif
6703#ifdef _SC_NL_TEXTMAX
6704 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6705#endif
6706#ifdef _SC_NPROCESSORS_CONF
6707 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6708#endif
6709#ifdef _SC_NPROCESSORS_ONLN
6710 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6711#endif
Fred Draked86ed291999-12-15 15:34:33 +00006712#ifdef _SC_NPROC_CONF
6713 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6714#endif
6715#ifdef _SC_NPROC_ONLN
6716 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6717#endif
Fred Drakec9680921999-12-13 16:37:25 +00006718#ifdef _SC_NZERO
6719 {"SC_NZERO", _SC_NZERO},
6720#endif
6721#ifdef _SC_OPEN_MAX
6722 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6723#endif
6724#ifdef _SC_PAGESIZE
6725 {"SC_PAGESIZE", _SC_PAGESIZE},
6726#endif
6727#ifdef _SC_PAGE_SIZE
6728 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6729#endif
6730#ifdef _SC_PASS_MAX
6731 {"SC_PASS_MAX", _SC_PASS_MAX},
6732#endif
6733#ifdef _SC_PHYS_PAGES
6734 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6735#endif
6736#ifdef _SC_PII
6737 {"SC_PII", _SC_PII},
6738#endif
6739#ifdef _SC_PII_INTERNET
6740 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6741#endif
6742#ifdef _SC_PII_INTERNET_DGRAM
6743 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6744#endif
6745#ifdef _SC_PII_INTERNET_STREAM
6746 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6747#endif
6748#ifdef _SC_PII_OSI
6749 {"SC_PII_OSI", _SC_PII_OSI},
6750#endif
6751#ifdef _SC_PII_OSI_CLTS
6752 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6753#endif
6754#ifdef _SC_PII_OSI_COTS
6755 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6756#endif
6757#ifdef _SC_PII_OSI_M
6758 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6759#endif
6760#ifdef _SC_PII_SOCKET
6761 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6762#endif
6763#ifdef _SC_PII_XTI
6764 {"SC_PII_XTI", _SC_PII_XTI},
6765#endif
6766#ifdef _SC_POLL
6767 {"SC_POLL", _SC_POLL},
6768#endif
6769#ifdef _SC_PRIORITIZED_IO
6770 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6771#endif
6772#ifdef _SC_PRIORITY_SCHEDULING
6773 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6774#endif
6775#ifdef _SC_REALTIME_SIGNALS
6776 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6777#endif
6778#ifdef _SC_RE_DUP_MAX
6779 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6780#endif
6781#ifdef _SC_RTSIG_MAX
6782 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6783#endif
6784#ifdef _SC_SAVED_IDS
6785 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6786#endif
6787#ifdef _SC_SCHAR_MAX
6788 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6789#endif
6790#ifdef _SC_SCHAR_MIN
6791 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6792#endif
6793#ifdef _SC_SELECT
6794 {"SC_SELECT", _SC_SELECT},
6795#endif
6796#ifdef _SC_SEMAPHORES
6797 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6798#endif
6799#ifdef _SC_SEM_NSEMS_MAX
6800 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6801#endif
6802#ifdef _SC_SEM_VALUE_MAX
6803 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6804#endif
6805#ifdef _SC_SHARED_MEMORY_OBJECTS
6806 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6807#endif
6808#ifdef _SC_SHRT_MAX
6809 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6810#endif
6811#ifdef _SC_SHRT_MIN
6812 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6813#endif
6814#ifdef _SC_SIGQUEUE_MAX
6815 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6816#endif
6817#ifdef _SC_SIGRT_MAX
6818 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6819#endif
6820#ifdef _SC_SIGRT_MIN
6821 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6822#endif
Fred Draked86ed291999-12-15 15:34:33 +00006823#ifdef _SC_SOFTPOWER
6824 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6825#endif
Fred Drakec9680921999-12-13 16:37:25 +00006826#ifdef _SC_SPLIT_CACHE
6827 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6828#endif
6829#ifdef _SC_SSIZE_MAX
6830 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6831#endif
6832#ifdef _SC_STACK_PROT
6833 {"SC_STACK_PROT", _SC_STACK_PROT},
6834#endif
6835#ifdef _SC_STREAM_MAX
6836 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6837#endif
6838#ifdef _SC_SYNCHRONIZED_IO
6839 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6840#endif
6841#ifdef _SC_THREADS
6842 {"SC_THREADS", _SC_THREADS},
6843#endif
6844#ifdef _SC_THREAD_ATTR_STACKADDR
6845 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6846#endif
6847#ifdef _SC_THREAD_ATTR_STACKSIZE
6848 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6849#endif
6850#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6851 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6852#endif
6853#ifdef _SC_THREAD_KEYS_MAX
6854 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6855#endif
6856#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6857 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6858#endif
6859#ifdef _SC_THREAD_PRIO_INHERIT
6860 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6861#endif
6862#ifdef _SC_THREAD_PRIO_PROTECT
6863 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6864#endif
6865#ifdef _SC_THREAD_PROCESS_SHARED
6866 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6867#endif
6868#ifdef _SC_THREAD_SAFE_FUNCTIONS
6869 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6870#endif
6871#ifdef _SC_THREAD_STACK_MIN
6872 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6873#endif
6874#ifdef _SC_THREAD_THREADS_MAX
6875 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6876#endif
6877#ifdef _SC_TIMERS
6878 {"SC_TIMERS", _SC_TIMERS},
6879#endif
6880#ifdef _SC_TIMER_MAX
6881 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6882#endif
6883#ifdef _SC_TTY_NAME_MAX
6884 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6885#endif
6886#ifdef _SC_TZNAME_MAX
6887 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6888#endif
6889#ifdef _SC_T_IOV_MAX
6890 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6891#endif
6892#ifdef _SC_UCHAR_MAX
6893 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6894#endif
6895#ifdef _SC_UINT_MAX
6896 {"SC_UINT_MAX", _SC_UINT_MAX},
6897#endif
6898#ifdef _SC_UIO_MAXIOV
6899 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6900#endif
6901#ifdef _SC_ULONG_MAX
6902 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6903#endif
6904#ifdef _SC_USHRT_MAX
6905 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6906#endif
6907#ifdef _SC_VERSION
6908 {"SC_VERSION", _SC_VERSION},
6909#endif
6910#ifdef _SC_WORD_BIT
6911 {"SC_WORD_BIT", _SC_WORD_BIT},
6912#endif
6913#ifdef _SC_XBS5_ILP32_OFF32
6914 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6915#endif
6916#ifdef _SC_XBS5_ILP32_OFFBIG
6917 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6918#endif
6919#ifdef _SC_XBS5_LP64_OFF64
6920 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6921#endif
6922#ifdef _SC_XBS5_LPBIG_OFFBIG
6923 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6924#endif
6925#ifdef _SC_XOPEN_CRYPT
6926 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6927#endif
6928#ifdef _SC_XOPEN_ENH_I18N
6929 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6930#endif
6931#ifdef _SC_XOPEN_LEGACY
6932 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6933#endif
6934#ifdef _SC_XOPEN_REALTIME
6935 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6936#endif
6937#ifdef _SC_XOPEN_REALTIME_THREADS
6938 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6939#endif
6940#ifdef _SC_XOPEN_SHM
6941 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6942#endif
6943#ifdef _SC_XOPEN_UNIX
6944 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6945#endif
6946#ifdef _SC_XOPEN_VERSION
6947 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6948#endif
6949#ifdef _SC_XOPEN_XCU_VERSION
6950 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6951#endif
6952#ifdef _SC_XOPEN_XPG2
6953 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6954#endif
6955#ifdef _SC_XOPEN_XPG3
6956 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6957#endif
6958#ifdef _SC_XOPEN_XPG4
6959 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6960#endif
6961};
6962
6963static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006964conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006965{
6966 return conv_confname(arg, valuep, posix_constants_sysconf,
6967 sizeof(posix_constants_sysconf)
6968 / sizeof(struct constdef));
6969}
6970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006971PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006972"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006973Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006974
6975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006976posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006977{
6978 PyObject *result = NULL;
6979 int name;
6980
6981 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6982 int value;
6983
6984 errno = 0;
6985 value = sysconf(name);
6986 if (value == -1 && errno != 0)
6987 posix_error();
6988 else
6989 result = PyInt_FromLong(value);
6990 }
6991 return result;
6992}
6993#endif
6994
6995
Fred Drakebec628d1999-12-15 18:31:10 +00006996/* This code is used to ensure that the tables of configuration value names
6997 * are in sorted order as required by conv_confname(), and also to build the
6998 * the exported dictionaries that are used to publish information about the
6999 * names available on the host platform.
7000 *
7001 * Sorting the table at runtime ensures that the table is properly ordered
7002 * when used, even for platforms we're not able to test on. It also makes
7003 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007004 */
Fred Drakebec628d1999-12-15 18:31:10 +00007005
7006static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007007cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007008{
7009 const struct constdef *c1 =
7010 (const struct constdef *) v1;
7011 const struct constdef *c2 =
7012 (const struct constdef *) v2;
7013
7014 return strcmp(c1->name, c2->name);
7015}
7016
7017static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007018setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007019 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007020{
Fred Drakebec628d1999-12-15 18:31:10 +00007021 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007022 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007023
7024 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7025 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007026 if (d == NULL)
7027 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007028
Barry Warsaw3155db32000-04-13 15:20:40 +00007029 for (i=0; i < tablesize; ++i) {
7030 PyObject *o = PyInt_FromLong(table[i].value);
7031 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7032 Py_XDECREF(o);
7033 Py_DECREF(d);
7034 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007035 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007036 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007037 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007038 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007039}
7040
Fred Drakebec628d1999-12-15 18:31:10 +00007041/* Return -1 on failure, 0 on success. */
7042static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007043setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007044{
7045#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007046 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007047 sizeof(posix_constants_pathconf)
7048 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007049 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007050 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007051#endif
7052#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007053 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007054 sizeof(posix_constants_confstr)
7055 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007056 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007057 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007058#endif
7059#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007060 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007061 sizeof(posix_constants_sysconf)
7062 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007063 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007064 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007065#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007066 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007067}
Fred Draked86ed291999-12-15 15:34:33 +00007068
7069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007071"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007072Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007073in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007074
7075static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007076posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007077{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 abort();
7079 /*NOTREACHED*/
7080 Py_FatalError("abort() called from Python code didn't abort!");
7081 return NULL;
7082}
Fred Drakebec628d1999-12-15 18:31:10 +00007083
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007084#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007085PyDoc_STRVAR(win32_startfile__doc__,
7086"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007087\n\
7088This acts like double-clicking the file in Explorer, or giving the file\n\
7089name as an argument to the DOS \"start\" command: the file is opened\n\
7090with whatever application (if any) its extension is associated.\n\
7091\n\
7092startfile returns as soon as the associated application is launched.\n\
7093There is no option to wait for the application to close, and no way\n\
7094to retrieve the application's exit status.\n\
7095\n\
7096The filepath is relative to the current directory. If you want to use\n\
7097an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007098the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007099
7100static PyObject *
7101win32_startfile(PyObject *self, PyObject *args)
7102{
7103 char *filepath;
7104 HINSTANCE rc;
7105 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7106 return NULL;
7107 Py_BEGIN_ALLOW_THREADS
7108 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7109 Py_END_ALLOW_THREADS
7110 if (rc <= (HINSTANCE)32)
7111 return win32_error("startfile", filepath);
7112 Py_INCREF(Py_None);
7113 return Py_None;
7114}
7115#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007116
Martin v. Löwis438b5342002-12-27 10:16:42 +00007117#ifdef HAVE_GETLOADAVG
7118PyDoc_STRVAR(posix_getloadavg__doc__,
7119"getloadavg() -> (float, float, float)\n\n\
7120Return the number of processes in the system run queue averaged over\n\
7121the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7122was unobtainable");
7123
7124static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007125posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007126{
7127 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007128 if (getloadavg(loadavg, 3)!=3) {
7129 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7130 return NULL;
7131 } else
7132 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7133}
7134#endif
7135
7136
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007137static PyMethodDef posix_methods[] = {
7138 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7139#ifdef HAVE_TTYNAME
7140 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7141#endif
7142 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7143 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007144#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007145 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007146#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007147#ifdef HAVE_LCHOWN
7148 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7149#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007150#ifdef HAVE_CHROOT
7151 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7152#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007153#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007154 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007156#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007157 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007158#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007159 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007160#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007161#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007162#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007163 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007164#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007165 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7166 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7167 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007168#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007170#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007171#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007172 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007173#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007174 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7175 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7176 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007177 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007178#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007180#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007181#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007182 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007183#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007184 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007185#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007186 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007187#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007188 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7189 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7190 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007191#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007192 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007193#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007194 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007195#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7197 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007198#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007199#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7201 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007202#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007203#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007204 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007205#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007206#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007207 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007208#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007209#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007210 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007211#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007212#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007213 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007214#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007215#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007216 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007217#endif /* HAVE_GETEGID */
7218#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007219 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007220#endif /* HAVE_GETEUID */
7221#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007222 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007223#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007224#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007225 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007227 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007228#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007229 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007230#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007231#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007232 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007233#endif /* HAVE_GETPPID */
7234#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007235 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007236#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007237#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007238 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007239#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007240#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007241 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007242#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007243#ifdef HAVE_KILLPG
7244 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7245#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007246#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007247 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007248#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007249#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007250 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007251#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007252 {"popen2", win32_popen2, METH_VARARGS},
7253 {"popen3", win32_popen3, METH_VARARGS},
7254 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007255 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007256#else
7257#if defined(PYOS_OS2) && defined(PYCC_GCC)
7258 {"popen2", os2emx_popen2, METH_VARARGS},
7259 {"popen3", os2emx_popen3, METH_VARARGS},
7260 {"popen4", os2emx_popen4, METH_VARARGS},
7261#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007262#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007263#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007264#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007265 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007266#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007267#ifdef HAVE_SETEUID
7268 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7269#endif /* HAVE_SETEUID */
7270#ifdef HAVE_SETEGID
7271 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7272#endif /* HAVE_SETEGID */
7273#ifdef HAVE_SETREUID
7274 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7275#endif /* HAVE_SETREUID */
7276#ifdef HAVE_SETREGID
7277 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7278#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007279#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007280 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007281#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007282#ifdef HAVE_SETGROUPS
7283 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7284#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007285#ifdef HAVE_GETPGID
7286 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7287#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007288#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007289 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007290#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007291#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007292 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007293#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007294#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007295 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007296#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007297#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007298 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007299#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007300#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007301 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007302#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007303#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007304 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007305#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007306#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007307 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007308#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007309 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7310 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7311 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7312 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7313 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7314 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7315 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7316 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7317 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007318 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007319#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007320 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007321#endif
7322#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007323 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007324#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007325#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007326 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7327#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007328#ifdef HAVE_DEVICE_MACROS
7329 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7330 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7331 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007333#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007334 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007335#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007336#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007337 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007338#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007339#ifdef HAVE_UNSETENV
7340 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7341#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007342#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007343 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007344#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007345#ifdef HAVE_FCHDIR
7346 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7347#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007348#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007349 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007350#endif
7351#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007352 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007353#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007354#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007355#ifdef WCOREDUMP
7356 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7357#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007358#ifdef WIFCONTINUED
7359 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7360#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007361#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007362 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007363#endif /* WIFSTOPPED */
7364#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007366#endif /* WIFSIGNALED */
7367#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007368 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007369#endif /* WIFEXITED */
7370#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007371 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007372#endif /* WEXITSTATUS */
7373#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007374 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007375#endif /* WTERMSIG */
7376#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007377 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007378#endif /* WSTOPSIG */
7379#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007380#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007381 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007382#endif
7383#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007384 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007385#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007386#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007387 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007388#endif
7389#ifdef HAVE_TEMPNAM
7390 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7391#endif
7392#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007393 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394#endif
Fred Drakec9680921999-12-13 16:37:25 +00007395#ifdef HAVE_CONFSTR
7396 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7397#endif
7398#ifdef HAVE_SYSCONF
7399 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7400#endif
7401#ifdef HAVE_FPATHCONF
7402 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7403#endif
7404#ifdef HAVE_PATHCONF
7405 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7406#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007407 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007408#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007409 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7410#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007411#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007412 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007413#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007414 {NULL, NULL} /* Sentinel */
7415};
7416
7417
Barry Warsaw4a342091996-12-19 23:50:02 +00007418static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007419ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007420{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007421 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007422}
7423
Guido van Rossumd48f2521997-12-05 22:19:34 +00007424#if defined(PYOS_OS2)
7425/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007426static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007427{
7428 APIRET rc;
7429 ULONG values[QSV_MAX+1];
7430 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007431 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007432
7433 Py_BEGIN_ALLOW_THREADS
7434 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7435 Py_END_ALLOW_THREADS
7436
7437 if (rc != NO_ERROR) {
7438 os2_error(rc);
7439 return -1;
7440 }
7441
Fred Drake4d1e64b2002-04-15 19:40:07 +00007442 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7443 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7444 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7445 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7446 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7447 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7448 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007449
7450 switch (values[QSV_VERSION_MINOR]) {
7451 case 0: ver = "2.00"; break;
7452 case 10: ver = "2.10"; break;
7453 case 11: ver = "2.11"; break;
7454 case 30: ver = "3.00"; break;
7455 case 40: ver = "4.00"; break;
7456 case 50: ver = "5.00"; break;
7457 default:
Tim Peters885d4572001-11-28 20:27:42 +00007458 PyOS_snprintf(tmp, sizeof(tmp),
7459 "%d-%d", values[QSV_VERSION_MAJOR],
7460 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007461 ver = &tmp[0];
7462 }
7463
7464 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007465 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007466 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007467
7468 /* Add Indicator of Which Drive was Used to Boot the System */
7469 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7470 tmp[1] = ':';
7471 tmp[2] = '\0';
7472
Fred Drake4d1e64b2002-04-15 19:40:07 +00007473 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007474}
7475#endif
7476
Barry Warsaw4a342091996-12-19 23:50:02 +00007477static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007478all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007479{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007480#ifdef F_OK
7481 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007482#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007483#ifdef R_OK
7484 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007485#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007486#ifdef W_OK
7487 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007488#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007489#ifdef X_OK
7490 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007491#endif
Fred Drakec9680921999-12-13 16:37:25 +00007492#ifdef NGROUPS_MAX
7493 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7494#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007495#ifdef TMP_MAX
7496 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7497#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007498#ifdef WCONTINUED
7499 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7500#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007501#ifdef WNOHANG
7502 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007503#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007504#ifdef WUNTRACED
7505 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7506#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007507#ifdef O_RDONLY
7508 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7509#endif
7510#ifdef O_WRONLY
7511 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7512#endif
7513#ifdef O_RDWR
7514 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7515#endif
7516#ifdef O_NDELAY
7517 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7518#endif
7519#ifdef O_NONBLOCK
7520 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7521#endif
7522#ifdef O_APPEND
7523 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7524#endif
7525#ifdef O_DSYNC
7526 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7527#endif
7528#ifdef O_RSYNC
7529 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7530#endif
7531#ifdef O_SYNC
7532 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7533#endif
7534#ifdef O_NOCTTY
7535 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7536#endif
7537#ifdef O_CREAT
7538 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7539#endif
7540#ifdef O_EXCL
7541 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7542#endif
7543#ifdef O_TRUNC
7544 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7545#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007546#ifdef O_BINARY
7547 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7548#endif
7549#ifdef O_TEXT
7550 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7551#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007552#ifdef O_LARGEFILE
7553 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7554#endif
7555
Tim Peters5aa91602002-01-30 05:46:57 +00007556/* MS Windows */
7557#ifdef O_NOINHERIT
7558 /* Don't inherit in child processes. */
7559 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7560#endif
7561#ifdef _O_SHORT_LIVED
7562 /* Optimize for short life (keep in memory). */
7563 /* MS forgot to define this one with a non-underscore form too. */
7564 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7565#endif
7566#ifdef O_TEMPORARY
7567 /* Automatically delete when last handle is closed. */
7568 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7569#endif
7570#ifdef O_RANDOM
7571 /* Optimize for random access. */
7572 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7573#endif
7574#ifdef O_SEQUENTIAL
7575 /* Optimize for sequential access. */
7576 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7577#endif
7578
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007579/* GNU extensions. */
7580#ifdef O_DIRECT
7581 /* Direct disk access. */
7582 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7583#endif
7584#ifdef O_DIRECTORY
7585 /* Must be a directory. */
7586 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7587#endif
7588#ifdef O_NOFOLLOW
7589 /* Do not follow links. */
7590 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7591#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007592
Barry Warsaw5676bd12003-01-07 20:57:09 +00007593 /* These come from sysexits.h */
7594#ifdef EX_OK
7595 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007596#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007597#ifdef EX_USAGE
7598 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007599#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007600#ifdef EX_DATAERR
7601 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007602#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007603#ifdef EX_NOINPUT
7604 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007605#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007606#ifdef EX_NOUSER
7607 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007608#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007609#ifdef EX_NOHOST
7610 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007611#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007612#ifdef EX_UNAVAILABLE
7613 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007614#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007615#ifdef EX_SOFTWARE
7616 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007617#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007618#ifdef EX_OSERR
7619 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007620#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007621#ifdef EX_OSFILE
7622 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007623#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007624#ifdef EX_CANTCREAT
7625 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007626#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007627#ifdef EX_IOERR
7628 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007629#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007630#ifdef EX_TEMPFAIL
7631 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007632#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007633#ifdef EX_PROTOCOL
7634 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007635#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007636#ifdef EX_NOPERM
7637 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007638#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007639#ifdef EX_CONFIG
7640 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007641#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007642#ifdef EX_NOTFOUND
7643 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007644#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007645
Guido van Rossum246bc171999-02-01 23:54:31 +00007646#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007647#if defined(PYOS_OS2) && defined(PYCC_GCC)
7648 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7649 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7650 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7651 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7652 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7653 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7654 if (ins(d, "P_PM", (long)P_PM)) return -1;
7655 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7656 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7657 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7658 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7659 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7660 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7661 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7662 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7663 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7664 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7665 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7666 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7667 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7668#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007669 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7670 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7671 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7672 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7673 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007674#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007675#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007676
Guido van Rossumd48f2521997-12-05 22:19:34 +00007677#if defined(PYOS_OS2)
7678 if (insertvalues(d)) return -1;
7679#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007680 return 0;
7681}
7682
7683
Tim Peters5aa91602002-01-30 05:46:57 +00007684#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007685#define INITFUNC initnt
7686#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007687
7688#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007689#define INITFUNC initos2
7690#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007691
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007692#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007693#define INITFUNC initposix
7694#define MODNAME "posix"
7695#endif
7696
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007697PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007698INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007699{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007700 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007701
Fred Drake4d1e64b2002-04-15 19:40:07 +00007702 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007703 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007704 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007705
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007706 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007708 Py_XINCREF(v);
7709 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007710 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007711 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007712
Fred Drake4d1e64b2002-04-15 19:40:07 +00007713 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007714 return;
7715
Fred Drake4d1e64b2002-04-15 19:40:07 +00007716 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007717 return;
7718
Fred Drake4d1e64b2002-04-15 19:40:07 +00007719 Py_INCREF(PyExc_OSError);
7720 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007721
Guido van Rossumb3d39562000-01-31 18:41:26 +00007722#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007723 if (posix_putenv_garbage == NULL)
7724 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007725#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007726
Guido van Rossum14648392001-12-08 18:02:58 +00007727 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007728 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7729 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7730 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007731 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007732 structseq_new = StatResultType.tp_new;
7733 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007734 Py_INCREF((PyObject*) &StatResultType);
7735 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007736
Guido van Rossum14648392001-12-08 18:02:58 +00007737 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007738 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007739 Py_INCREF((PyObject*) &StatVFSResultType);
7740 PyModule_AddObject(m, "statvfs_result",
7741 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007742}