blob: 482bba95cbd8c2563b04b832990ad23807bbab31 [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 }
Just van Rossum46c97842003-02-25 21:42:15 +00001798#ifdef Py_USING_UNICODE
1799 if (Py_FileSystemDefaultEncoding != NULL) {
1800 PyObject *w;
1801
1802 w = PyUnicode_FromEncodedObject(v,
1803 Py_FileSystemDefaultEncoding,
1804 "strict");
1805 Py_DECREF(v);
1806 v = w;
1807 if (v == NULL) {
1808 Py_DECREF(d);
1809 d = NULL;
1810 break;
1811 }
1812 /* attempt to convert to ASCII */
1813 w = PyUnicode_AsASCIIString(v);
1814 if (w != NULL) {
1815 Py_DECREF(v);
1816 v = w;
1817 }
1818 else
1819 PyErr_Clear();
1820 }
1821#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001822 if (PyList_Append(d, v) != 0) {
1823 Py_DECREF(v);
1824 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825 d = NULL;
1826 break;
1827 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001828 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001829 }
1830 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001831
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001832 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001833
Tim Peters0bb44a42000-09-15 07:44:49 +00001834#endif /* which OS */
1835} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001837#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001838/* A helper function for abspath on win32 */
1839static PyObject *
1840posix__getfullpathname(PyObject *self, PyObject *args)
1841{
1842 /* assume encoded strings wont more than double no of chars */
1843 char inbuf[MAX_PATH*2];
1844 char *inbufp = inbuf;
1845 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1846 char outbuf[MAX_PATH*2];
1847 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001848#ifdef Py_WIN_WIDE_FILENAMES
1849 if (unicode_file_names()) {
1850 PyUnicodeObject *po;
1851 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1852 Py_UNICODE woutbuf[MAX_PATH*2];
1853 Py_UNICODE *wtemp;
1854 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1855 sizeof(woutbuf)/sizeof(woutbuf[0]),
1856 woutbuf, &wtemp))
1857 return win32_error("GetFullPathName", "");
1858 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1859 }
1860 /* Drop the argument parsing error as narrow strings
1861 are also valid. */
1862 PyErr_Clear();
1863 }
1864#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001865 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1866 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001867 &insize))
1868 return NULL;
1869 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1870 outbuf, &temp))
1871 return win32_error("GetFullPathName", inbuf);
1872 return PyString_FromString(outbuf);
1873} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001874#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001877"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001881posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001882{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001883 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001884 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001885 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001886
1887#ifdef Py_WIN_WIDE_FILENAMES
1888 if (unicode_file_names()) {
1889 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001890 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001891 Py_BEGIN_ALLOW_THREADS
1892 /* PyUnicode_AS_UNICODE OK without thread lock as
1893 it is a simple dereference. */
1894 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1895 Py_END_ALLOW_THREADS
1896 if (res < 0)
1897 return posix_error();
1898 Py_INCREF(Py_None);
1899 return Py_None;
1900 }
1901 /* Drop the argument parsing error as narrow strings
1902 are also valid. */
1903 PyErr_Clear();
1904 }
1905#endif
1906
Tim Peters5aa91602002-01-30 05:46:57 +00001907 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001908 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001909 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001910 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001911#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001912 res = mkdir(path);
1913#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001914 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001915#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001916 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001917 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001918 return posix_error_with_allocated_filename(path);
1919 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001920 Py_INCREF(Py_None);
1921 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001922}
1923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001924
Guido van Rossumb6775db1994-08-01 11:34:53 +00001925#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001926#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1927#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1928#include <sys/resource.h>
1929#endif
1930#endif
1931
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001932PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001933"nice(inc) -> new_priority\n\n\
1934Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001935
Barry Warsaw53699e91996-12-10 23:23:01 +00001936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001938{
1939 int increment, value;
1940
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001941 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001942 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001943
1944 /* There are two flavours of 'nice': one that returns the new
1945 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001946 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1947 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001948
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001949 If we are of the nice family that returns the new priority, we
1950 need to clear errno before the call, and check if errno is filled
1951 before calling posix_error() on a returnvalue of -1, because the
1952 -1 may be the actual new priority! */
1953
1954 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001955 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001956#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001957 if (value == 0)
1958 value = getpriority(PRIO_PROCESS, 0);
1959#endif
1960 if (value == -1 && errno != 0)
1961 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001962 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001963 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001964}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001965#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001969"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001971
Barry Warsaw53699e91996-12-10 23:23:01 +00001972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001973posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001975#ifdef MS_WINDOWS
1976 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1977#else
1978 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1979#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001980}
1981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001984"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001985Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986
Barry Warsaw53699e91996-12-10 23:23:01 +00001987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001988posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001989{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001990#ifdef MS_WINDOWS
1991 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1992#else
1993 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1994#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001995}
1996
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001998PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001999"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002000Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002001
Barry Warsaw53699e91996-12-10 23:23:01 +00002002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002003posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002004{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005#ifdef MS_WINDOWS
2006 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
2007#else
2008 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2009#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002010}
2011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002012
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002013#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002015"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Barry Warsaw53699e91996-12-10 23:23:01 +00002018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002019posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002020{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002021 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002022 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002023 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002024 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002025 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002026 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 Py_END_ALLOW_THREADS
2028 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002030#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Barry Warsaw53699e91996-12-10 23:23:01 +00002037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002038posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002039{
2040 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002041 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002043 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044 if (i < 0)
2045 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002046 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047}
2048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002051"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002055"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002056Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Barry Warsaw53699e91996-12-10 23:23:01 +00002058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002059posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002061#ifdef MS_WINDOWS
2062 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2063#else
2064 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2065#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002066}
2067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Guido van Rossumb6775db1994-08-01 11:34:53 +00002069#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002072Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002073
Barry Warsaw53699e91996-12-10 23:23:01 +00002074static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002075posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002076{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002077 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002078 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002081 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002082 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002083 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002084 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002085 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002086 u.sysname,
2087 u.nodename,
2088 u.release,
2089 u.version,
2090 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002091}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002092#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002093
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002094static int
2095extract_time(PyObject *t, long* sec, long* usec)
2096{
2097 long intval;
2098 if (PyFloat_Check(t)) {
2099 double tval = PyFloat_AsDouble(t);
2100 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2101 if (!intobj)
2102 return -1;
2103 intval = PyInt_AsLong(intobj);
2104 Py_DECREF(intobj);
2105 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002106 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002107 if (*usec < 0)
2108 /* If rounding gave us a negative number,
2109 truncate. */
2110 *usec = 0;
2111 return 0;
2112 }
2113 intval = PyInt_AsLong(t);
2114 if (intval == -1 && PyErr_Occurred())
2115 return -1;
2116 *sec = intval;
2117 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002118 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002119}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002121PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002122"utime(path, (atime, utime))\n\
2123utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002124Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002126
Barry Warsaw53699e91996-12-10 23:23:01 +00002127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002128posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002129{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002130 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002131 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002132 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002133 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002134
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002135#if defined(HAVE_UTIMES)
2136 struct timeval buf[2];
2137#define ATIME buf[0].tv_sec
2138#define MTIME buf[1].tv_sec
2139#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002140/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002141 struct utimbuf buf;
2142#define ATIME buf.actime
2143#define MTIME buf.modtime
2144#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002145#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002146 time_t buf[2];
2147#define ATIME buf[0]
2148#define MTIME buf[1]
2149#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002150#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002151
Barry Warsaw3cef8562000-05-01 16:17:24 +00002152 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002153 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002154 if (arg == Py_None) {
2155 /* optional time values not given */
2156 Py_BEGIN_ALLOW_THREADS
2157 res = utime(path, NULL);
2158 Py_END_ALLOW_THREADS
2159 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002160 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002161 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002162 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002163 return NULL;
2164 }
2165 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002166 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2167 &atime, &ausec) == -1)
2168 return NULL;
2169 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2170 &mtime, &musec) == -1)
2171 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002172 ATIME = atime;
2173 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002174#ifdef HAVE_UTIMES
2175 buf[0].tv_usec = ausec;
2176 buf[1].tv_usec = musec;
2177 Py_BEGIN_ALLOW_THREADS
2178 res = utimes(path, buf);
2179 Py_END_ALLOW_THREADS
2180#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002181 Py_BEGIN_ALLOW_THREADS
2182 res = utime(path, UTIME_ARG);
2183 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002184#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002185 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002186 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002187 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002188 Py_INCREF(Py_None);
2189 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002190#undef UTIME_ARG
2191#undef ATIME
2192#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002193}
2194
Guido van Rossum85e3b011991-06-03 12:42:10 +00002195
Guido van Rossum3b066191991-06-04 19:40:25 +00002196/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002198PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002199"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002200Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Barry Warsaw53699e91996-12-10 23:23:01 +00002202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002203posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002204{
2205 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002206 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002207 return NULL;
2208 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002209 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002210}
2211
Martin v. Löwis114619e2002-10-07 06:44:21 +00002212#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2213static void
2214free_string_array(char **array, int count)
2215{
2216 int i;
2217 for (i = 0; i < count; i++)
2218 PyMem_Free(array[i]);
2219 PyMem_DEL(array);
2220}
2221#endif
2222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002223
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002224#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002225PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002226"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227Execute an executable path with arguments, replacing current process.\n\
2228\n\
2229 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002230 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002231
Barry Warsaw53699e91996-12-10 23:23:01 +00002232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002233posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002234{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002235 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002236 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002237 char **argvlist;
2238 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002239 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002240
Guido van Rossum89b33251993-10-22 14:26:06 +00002241 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002242 argv is a list or tuple of strings. */
2243
Martin v. Löwis114619e2002-10-07 06:44:21 +00002244 if (!PyArg_ParseTuple(args, "etO:execv",
2245 Py_FileSystemDefaultEncoding,
2246 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002247 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002248 if (PyList_Check(argv)) {
2249 argc = PyList_Size(argv);
2250 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002251 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002252 else if (PyTuple_Check(argv)) {
2253 argc = PyTuple_Size(argv);
2254 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002255 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002256 else {
Fred Drake661ea262000-10-24 19:57:45 +00002257 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002258 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002259 return NULL;
2260 }
2261
2262 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002263 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002264 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002265 return NULL;
2266 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002267
Barry Warsaw53699e91996-12-10 23:23:01 +00002268 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002269 if (argvlist == NULL) {
2270 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002271 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002272 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002273 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002274 if (!PyArg_Parse((*getitem)(argv, i), "et",
2275 Py_FileSystemDefaultEncoding,
2276 &argvlist[i])) {
2277 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002278 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002279 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002280 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002281 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002282
Guido van Rossum85e3b011991-06-03 12:42:10 +00002283 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002284 }
2285 argvlist[argc] = NULL;
2286
Guido van Rossumb6775db1994-08-01 11:34:53 +00002287#ifdef BAD_EXEC_PROTOTYPES
2288 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002289#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002290 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002291#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002292
Guido van Rossum85e3b011991-06-03 12:42:10 +00002293 /* If we get here it's definitely an error */
2294
Martin v. Löwis114619e2002-10-07 06:44:21 +00002295 free_string_array(argvlist, argc);
2296 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002297 return posix_error();
2298}
2299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002301PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002302"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002303Execute a path with arguments and environment, replacing current process.\n\
2304\n\
2305 path: path of executable file\n\
2306 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002307 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002308
Barry Warsaw53699e91996-12-10 23:23:01 +00002309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002310posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002311{
2312 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002313 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002314 char **argvlist;
2315 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002316 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002317 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002318 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002320
2321 /* execve has three arguments: (path, argv, env), where
2322 argv is a list or tuple of strings and env is a dictionary
2323 like posix.environ. */
2324
Martin v. Löwis114619e2002-10-07 06:44:21 +00002325 if (!PyArg_ParseTuple(args, "etOO:execve",
2326 Py_FileSystemDefaultEncoding,
2327 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002328 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002329 if (PyList_Check(argv)) {
2330 argc = PyList_Size(argv);
2331 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002332 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002333 else if (PyTuple_Check(argv)) {
2334 argc = PyTuple_Size(argv);
2335 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002336 }
2337 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002338 PyErr_SetString(PyExc_TypeError,
2339 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002340 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002341 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002342 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002343 PyErr_SetString(PyExc_TypeError,
2344 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002345 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002346 }
2347
Guido van Rossum50422b42000-04-26 20:34:28 +00002348 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002349 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002350 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002352 }
2353
Barry Warsaw53699e91996-12-10 23:23:01 +00002354 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002355 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002357 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002358 }
2359 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002360 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002361 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002362 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002363 &argvlist[i]))
2364 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002365 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002366 goto fail_1;
2367 }
2368 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002369 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002370 argvlist[argc] = NULL;
2371
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002372 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002373 if (i < 0)
2374 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002375 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002376 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002377 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002378 goto fail_1;
2379 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002380 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002381 keys = PyMapping_Keys(env);
2382 vals = PyMapping_Values(env);
2383 if (!keys || !vals)
2384 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002385 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2386 PyErr_SetString(PyExc_TypeError,
2387 "execve(): env.keys() or env.values() is not a list");
2388 goto fail_2;
2389 }
Tim Peters5aa91602002-01-30 05:46:57 +00002390
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002391 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002392 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002393 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002394
2395 key = PyList_GetItem(keys, pos);
2396 val = PyList_GetItem(vals, pos);
2397 if (!key || !val)
2398 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002399
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002400 if (!PyArg_Parse(
2401 key,
2402 "s;execve() arg 3 contains a non-string key",
2403 &k) ||
2404 !PyArg_Parse(
2405 val,
2406 "s;execve() arg 3 contains a non-string value",
2407 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002408 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002409 goto fail_2;
2410 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002411
2412#if defined(PYOS_OS2)
2413 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2414 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2415#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002416 len = PyString_Size(key) + PyString_Size(val) + 2;
2417 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002418 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002419 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002420 goto fail_2;
2421 }
Tim Petersc8996f52001-12-03 20:41:00 +00002422 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002423 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002424#if defined(PYOS_OS2)
2425 }
2426#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002427 }
2428 envlist[envc] = 0;
2429
Guido van Rossumb6775db1994-08-01 11:34:53 +00002430
2431#ifdef BAD_EXEC_PROTOTYPES
2432 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002433#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002434 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002435#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002436
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002437 /* If we get here it's definitely an error */
2438
2439 (void) posix_error();
2440
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002441 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002442 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002443 PyMem_DEL(envlist[envc]);
2444 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002445 fail_1:
2446 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002447 Py_XDECREF(vals);
2448 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002449 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002450 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002451 return NULL;
2452}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002453#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002455
Guido van Rossuma1065681999-01-25 23:20:23 +00002456#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002457PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002458"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002459Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002460\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002461 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002462 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002464
2465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002466posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002467{
2468 char *path;
2469 PyObject *argv;
2470 char **argvlist;
2471 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002472 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002473 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002474
2475 /* spawnv has three arguments: (mode, path, argv), where
2476 argv is a list or tuple of strings. */
2477
Martin v. Löwis114619e2002-10-07 06:44:21 +00002478 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2479 Py_FileSystemDefaultEncoding,
2480 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002481 return NULL;
2482 if (PyList_Check(argv)) {
2483 argc = PyList_Size(argv);
2484 getitem = PyList_GetItem;
2485 }
2486 else if (PyTuple_Check(argv)) {
2487 argc = PyTuple_Size(argv);
2488 getitem = PyTuple_GetItem;
2489 }
2490 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002491 PyErr_SetString(PyExc_TypeError,
2492 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002493 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002494 return NULL;
2495 }
2496
2497 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002498 if (argvlist == NULL) {
2499 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002500 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002501 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002502 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002503 if (!PyArg_Parse((*getitem)(argv, i), "et",
2504 Py_FileSystemDefaultEncoding,
2505 &argvlist[i])) {
2506 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002507 PyErr_SetString(
2508 PyExc_TypeError,
2509 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002510 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002511 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002512 }
2513 }
2514 argvlist[argc] = NULL;
2515
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002516#if defined(PYOS_OS2) && defined(PYCC_GCC)
2517 Py_BEGIN_ALLOW_THREADS
2518 spawnval = spawnv(mode, path, argvlist);
2519 Py_END_ALLOW_THREADS
2520#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002521 if (mode == _OLD_P_OVERLAY)
2522 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002523
Tim Peters25059d32001-12-07 20:35:43 +00002524 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002525 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002526 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002527#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002528
Martin v. Löwis114619e2002-10-07 06:44:21 +00002529 free_string_array(argvlist, argc);
2530 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002531
Fred Drake699f3522000-06-29 21:12:41 +00002532 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002533 return posix_error();
2534 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002535#if SIZEOF_LONG == SIZEOF_VOID_P
2536 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002537#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002538 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002539#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002540}
2541
2542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002544"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002545Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002546\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002547 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002548 path: path of executable file\n\
2549 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002550 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002551
2552static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002553posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002554{
2555 char *path;
2556 PyObject *argv, *env;
2557 char **argvlist;
2558 char **envlist;
2559 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2560 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002561 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002562 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002563 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002564
2565 /* spawnve has four arguments: (mode, path, argv, env), where
2566 argv is a list or tuple of strings and env is a dictionary
2567 like posix.environ. */
2568
Martin v. Löwis114619e2002-10-07 06:44:21 +00002569 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2570 Py_FileSystemDefaultEncoding,
2571 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002572 return NULL;
2573 if (PyList_Check(argv)) {
2574 argc = PyList_Size(argv);
2575 getitem = PyList_GetItem;
2576 }
2577 else if (PyTuple_Check(argv)) {
2578 argc = PyTuple_Size(argv);
2579 getitem = PyTuple_GetItem;
2580 }
2581 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002582 PyErr_SetString(PyExc_TypeError,
2583 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002584 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002585 }
2586 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002587 PyErr_SetString(PyExc_TypeError,
2588 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002589 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002590 }
2591
2592 argvlist = PyMem_NEW(char *, argc+1);
2593 if (argvlist == NULL) {
2594 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002595 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002596 }
2597 for (i = 0; i < argc; i++) {
2598 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002599 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002600 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002601 &argvlist[i]))
2602 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002603 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002604 goto fail_1;
2605 }
2606 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002607 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002608 argvlist[argc] = NULL;
2609
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002610 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002611 if (i < 0)
2612 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002613 envlist = PyMem_NEW(char *, i + 1);
2614 if (envlist == NULL) {
2615 PyErr_NoMemory();
2616 goto fail_1;
2617 }
2618 envc = 0;
2619 keys = PyMapping_Keys(env);
2620 vals = PyMapping_Values(env);
2621 if (!keys || !vals)
2622 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002623 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2624 PyErr_SetString(PyExc_TypeError,
2625 "spawnve(): env.keys() or env.values() is not a list");
2626 goto fail_2;
2627 }
Tim Peters5aa91602002-01-30 05:46:57 +00002628
Guido van Rossuma1065681999-01-25 23:20:23 +00002629 for (pos = 0; pos < i; pos++) {
2630 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002631 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002632
2633 key = PyList_GetItem(keys, pos);
2634 val = PyList_GetItem(vals, pos);
2635 if (!key || !val)
2636 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002637
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002638 if (!PyArg_Parse(
2639 key,
2640 "s;spawnve() arg 3 contains a non-string key",
2641 &k) ||
2642 !PyArg_Parse(
2643 val,
2644 "s;spawnve() arg 3 contains a non-string value",
2645 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002646 {
2647 goto fail_2;
2648 }
Tim Petersc8996f52001-12-03 20:41:00 +00002649 len = PyString_Size(key) + PyString_Size(val) + 2;
2650 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002651 if (p == NULL) {
2652 PyErr_NoMemory();
2653 goto fail_2;
2654 }
Tim Petersc8996f52001-12-03 20:41:00 +00002655 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002656 envlist[envc++] = p;
2657 }
2658 envlist[envc] = 0;
2659
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002660#if defined(PYOS_OS2) && defined(PYCC_GCC)
2661 Py_BEGIN_ALLOW_THREADS
2662 spawnval = spawnve(mode, path, argvlist, envlist);
2663 Py_END_ALLOW_THREADS
2664#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002665 if (mode == _OLD_P_OVERLAY)
2666 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002667
2668 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002669 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002670 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002671#endif
Tim Peters25059d32001-12-07 20:35:43 +00002672
Fred Drake699f3522000-06-29 21:12:41 +00002673 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002674 (void) posix_error();
2675 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002676#if SIZEOF_LONG == SIZEOF_VOID_P
2677 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002678#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002679 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002680#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002681
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002682 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002683 while (--envc >= 0)
2684 PyMem_DEL(envlist[envc]);
2685 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002686 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002687 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002688 Py_XDECREF(vals);
2689 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 fail_0:
2691 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002692 return res;
2693}
2694#endif /* HAVE_SPAWNV */
2695
2696
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002697#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002699"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002700Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2701\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002703
2704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002705posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002706{
Neal Norwitze241ce82003-02-17 18:17:05 +00002707 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002708 if (pid == -1)
2709 return posix_error();
2710 PyOS_AfterFork();
2711 return PyInt_FromLong((long)pid);
2712}
2713#endif
2714
2715
Guido van Rossumad0ee831995-03-01 10:34:45 +00002716#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002718"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002719Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721
Barry Warsaw53699e91996-12-10 23:23:01 +00002722static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002723posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002724{
Neal Norwitze241ce82003-02-17 18:17:05 +00002725 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002726 if (pid == -1)
2727 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002728 if (pid == 0)
2729 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002730 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002731}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002732#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002733
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002734#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002735#ifdef HAVE_PTY_H
2736#include <pty.h>
2737#else
2738#ifdef HAVE_LIBUTIL_H
2739#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002740#endif /* HAVE_LIBUTIL_H */
2741#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002742#ifdef HAVE_STROPTS_H
2743#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002744#endif
2745#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002746
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002747#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002748PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002749"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002750Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002751
2752static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002753posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002754{
2755 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002756#ifndef HAVE_OPENPTY
2757 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002758#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002759#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002760 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002761#ifdef sun
2762 extern char *ptsname();
2763#endif
2764#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002765
Thomas Wouters70c21a12000-07-14 14:28:33 +00002766#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002767 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2768 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002769#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002770 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2771 if (slave_name == NULL)
2772 return posix_error();
2773
2774 slave_fd = open(slave_name, O_RDWR);
2775 if (slave_fd < 0)
2776 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002777#else
2778 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2779 if (master_fd < 0)
2780 return posix_error();
2781 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002782 /* change permission of slave */
2783 if (grantpt(master_fd) < 0) {
2784 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002785 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002786 }
2787 /* unlock slave */
2788 if (unlockpt(master_fd) < 0) {
2789 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002790 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002791 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002792 signal(SIGCHLD, sig_saved);
2793 slave_name = ptsname(master_fd); /* get name of slave */
2794 if (slave_name == NULL)
2795 return posix_error();
2796 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2797 if (slave_fd < 0)
2798 return posix_error();
2799#ifndef __CYGWIN__
2800 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2801 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002802#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002803 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002804#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002805#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002806#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002807
Fred Drake8cef4cf2000-06-28 16:40:38 +00002808 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002809
Fred Drake8cef4cf2000-06-28 16:40:38 +00002810}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002811#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002812
2813#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002815"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002816Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2817Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002819
2820static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002821posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002822{
2823 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002824
Fred Drake8cef4cf2000-06-28 16:40:38 +00002825 pid = forkpty(&master_fd, NULL, NULL, NULL);
2826 if (pid == -1)
2827 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002828 if (pid == 0)
2829 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002830 return Py_BuildValue("(ii)", pid, master_fd);
2831}
2832#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002833
Guido van Rossumad0ee831995-03-01 10:34:45 +00002834#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002835PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002836"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838
Barry Warsaw53699e91996-12-10 23:23:01 +00002839static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002840posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002841{
Barry Warsaw53699e91996-12-10 23:23:01 +00002842 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002843}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002844#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Guido van Rossumad0ee831995-03-01 10:34:45 +00002847#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002849"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002850Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851
Barry Warsaw53699e91996-12-10 23:23:01 +00002852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002853posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002854{
Barry Warsaw53699e91996-12-10 23:23:01 +00002855 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002856}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002857#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002859
Guido van Rossumad0ee831995-03-01 10:34:45 +00002860#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002862"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002864
Barry Warsaw53699e91996-12-10 23:23:01 +00002865static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002866posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002867{
Barry Warsaw53699e91996-12-10 23:23:01 +00002868 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002869}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002870#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002872
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002874"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002878posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002879{
Barry Warsaw53699e91996-12-10 23:23:01 +00002880 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002881}
2882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002883
Fred Drakec9680921999-12-13 16:37:25 +00002884#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002885PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002886"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002887Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002888
2889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002890posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002891{
2892 PyObject *result = NULL;
2893
Fred Drakec9680921999-12-13 16:37:25 +00002894#ifdef NGROUPS_MAX
2895#define MAX_GROUPS NGROUPS_MAX
2896#else
2897 /* defined to be 16 on Solaris7, so this should be a small number */
2898#define MAX_GROUPS 64
2899#endif
2900 gid_t grouplist[MAX_GROUPS];
2901 int n;
2902
2903 n = getgroups(MAX_GROUPS, grouplist);
2904 if (n < 0)
2905 posix_error();
2906 else {
2907 result = PyList_New(n);
2908 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002909 int i;
2910 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002911 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002912 if (o == NULL) {
2913 Py_DECREF(result);
2914 result = NULL;
2915 break;
2916 }
2917 PyList_SET_ITEM(result, i, o);
2918 }
2919 }
2920 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002921
Fred Drakec9680921999-12-13 16:37:25 +00002922 return result;
2923}
2924#endif
2925
Martin v. Löwis606edc12002-06-13 21:09:11 +00002926#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002927PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002928"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002929Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002930
2931static PyObject *
2932posix_getpgid(PyObject *self, PyObject *args)
2933{
2934 int pid, pgid;
2935 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2936 return NULL;
2937 pgid = getpgid(pid);
2938 if (pgid < 0)
2939 return posix_error();
2940 return PyInt_FromLong((long)pgid);
2941}
2942#endif /* HAVE_GETPGID */
2943
2944
Guido van Rossumb6775db1994-08-01 11:34:53 +00002945#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002947"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002948Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Barry Warsaw53699e91996-12-10 23:23:01 +00002950static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002951posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002952{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002953#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002954 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002955#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002956 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002957#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002958}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002959#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Guido van Rossumb6775db1994-08-01 11:34:53 +00002962#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002964"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002966
Barry Warsaw53699e91996-12-10 23:23:01 +00002967static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002968posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002969{
Guido van Rossum64933891994-10-20 21:56:42 +00002970#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002971 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002972#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002973 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002974#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002975 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002976 Py_INCREF(Py_None);
2977 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002978}
2979
Guido van Rossumb6775db1994-08-01 11:34:53 +00002980#endif /* HAVE_SETPGRP */
2981
Guido van Rossumad0ee831995-03-01 10:34:45 +00002982#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002983PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002984"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002985Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986
Barry Warsaw53699e91996-12-10 23:23:01 +00002987static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002988posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002989{
Barry Warsaw53699e91996-12-10 23:23:01 +00002990 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002991}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002992#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002994
Fred Drake12c6e2d1999-12-14 21:25:03 +00002995#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002996PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002997"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002998Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002999
3000static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003001posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003002{
Neal Norwitze241ce82003-02-17 18:17:05 +00003003 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003004 char *name;
3005 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003006
Fred Drakea30680b2000-12-06 21:24:28 +00003007 errno = 0;
3008 name = getlogin();
3009 if (name == NULL) {
3010 if (errno)
3011 posix_error();
3012 else
3013 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003014 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003015 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003016 else
3017 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003018 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003019
Fred Drake12c6e2d1999-12-14 21:25:03 +00003020 return result;
3021}
3022#endif
3023
Guido van Rossumad0ee831995-03-01 10:34:45 +00003024#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003028
Barry Warsaw53699e91996-12-10 23:23:01 +00003029static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003030posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003031{
Barry Warsaw53699e91996-12-10 23:23:01 +00003032 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003033}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003034#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003036
Guido van Rossumad0ee831995-03-01 10:34:45 +00003037#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003038PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003039"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Barry Warsaw53699e91996-12-10 23:23:01 +00003042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003043posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003044{
3045 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003046 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003047 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003048#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003049 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3050 APIRET rc;
3051 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003052 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003053
3054 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3055 APIRET rc;
3056 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003057 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003058
3059 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003060 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003061#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003062 if (kill(pid, sig) == -1)
3063 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003064#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003065 Py_INCREF(Py_None);
3066 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003067}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003068#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003069
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003070#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003071PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003072"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003073Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003074
3075static PyObject *
3076posix_killpg(PyObject *self, PyObject *args)
3077{
3078 int pgid, sig;
3079 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3080 return NULL;
3081 if (killpg(pgid, sig) == -1)
3082 return posix_error();
3083 Py_INCREF(Py_None);
3084 return Py_None;
3085}
3086#endif
3087
Guido van Rossumc0125471996-06-28 18:55:32 +00003088#ifdef HAVE_PLOCK
3089
3090#ifdef HAVE_SYS_LOCK_H
3091#include <sys/lock.h>
3092#endif
3093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003094PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003095"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003096Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003097
Barry Warsaw53699e91996-12-10 23:23:01 +00003098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003099posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003100{
3101 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003102 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003103 return NULL;
3104 if (plock(op) == -1)
3105 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 Py_INCREF(Py_None);
3107 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003108}
3109#endif
3110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003111
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003112#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003113PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003114"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003115Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003116
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003117#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003118#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003119static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003120async_system(const char *command)
3121{
3122 char *p, errormsg[256], args[1024];
3123 RESULTCODES rcodes;
3124 APIRET rc;
3125 char *shell = getenv("COMSPEC");
3126 if (!shell)
3127 shell = "cmd";
3128
3129 strcpy(args, shell);
3130 p = &args[ strlen(args)+1 ];
3131 strcpy(p, "/c ");
3132 strcat(p, command);
3133 p += strlen(p) + 1;
3134 *p = '\0';
3135
3136 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003137 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003138 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003139 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003140 &rcodes, shell);
3141 return rc;
3142}
3143
Guido van Rossumd48f2521997-12-05 22:19:34 +00003144static FILE *
3145popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003146{
3147 HFILE rhan, whan;
3148 FILE *retfd = NULL;
3149 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3150
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151 if (rc != NO_ERROR) {
3152 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003153 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003154 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003155
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003156 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3157 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003158
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003159 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3160 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003161
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003162 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3163 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003164
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003165 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003166 }
3167
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003168 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3169 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003170
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003171 if (rc == NO_ERROR)
3172 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3173
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003174 close(oldfd); /* And Close Saved STDOUT Handle */
3175 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003176
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003177 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3178 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003179
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003180 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3181 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003182
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003183 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3184 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003185
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003186 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003187 }
3188
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003189 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3190 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003191
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003192 if (rc == NO_ERROR)
3193 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3194
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003195 close(oldfd); /* And Close Saved STDIN Handle */
3196 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003197
Guido van Rossumd48f2521997-12-05 22:19:34 +00003198 } else {
3199 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003200 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003201 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003202}
3203
3204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003205posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003206{
3207 char *name;
3208 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003209 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003210 FILE *fp;
3211 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003212 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003213 return NULL;
3214 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003215 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003216 Py_END_ALLOW_THREADS
3217 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003218 return os2_error(err);
3219
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003220 f = PyFile_FromFile(fp, name, mode, fclose);
3221 if (f != NULL)
3222 PyFile_SetBufSize(f, bufsize);
3223 return f;
3224}
3225
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003226#elif defined(PYCC_GCC)
3227
3228/* standard posix version of popen() support */
3229static PyObject *
3230posix_popen(PyObject *self, PyObject *args)
3231{
3232 char *name;
3233 char *mode = "r";
3234 int bufsize = -1;
3235 FILE *fp;
3236 PyObject *f;
3237 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3238 return NULL;
3239 Py_BEGIN_ALLOW_THREADS
3240 fp = popen(name, mode);
3241 Py_END_ALLOW_THREADS
3242 if (fp == NULL)
3243 return posix_error();
3244 f = PyFile_FromFile(fp, name, mode, pclose);
3245 if (f != NULL)
3246 PyFile_SetBufSize(f, bufsize);
3247 return f;
3248}
3249
3250/* fork() under OS/2 has lots'o'warts
3251 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3252 * most of this code is a ripoff of the win32 code, but using the
3253 * capabilities of EMX's C library routines
3254 */
3255
3256/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3257#define POPEN_1 1
3258#define POPEN_2 2
3259#define POPEN_3 3
3260#define POPEN_4 4
3261
3262static PyObject *_PyPopen(char *, int, int, int);
3263static int _PyPclose(FILE *file);
3264
3265/*
3266 * Internal dictionary mapping popen* file pointers to process handles,
3267 * for use when retrieving the process exit code. See _PyPclose() below
3268 * for more information on this dictionary's use.
3269 */
3270static PyObject *_PyPopenProcs = NULL;
3271
3272/* os2emx version of popen2()
3273 *
3274 * The result of this function is a pipe (file) connected to the
3275 * process's stdin, and a pipe connected to the process's stdout.
3276 */
3277
3278static PyObject *
3279os2emx_popen2(PyObject *self, PyObject *args)
3280{
3281 PyObject *f;
3282 int tm=0;
3283
3284 char *cmdstring;
3285 char *mode = "t";
3286 int bufsize = -1;
3287 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3288 return NULL;
3289
3290 if (*mode == 't')
3291 tm = O_TEXT;
3292 else if (*mode != 'b') {
3293 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3294 return NULL;
3295 } else
3296 tm = O_BINARY;
3297
3298 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3299
3300 return f;
3301}
3302
3303/*
3304 * Variation on os2emx.popen2
3305 *
3306 * The result of this function is 3 pipes - the process's stdin,
3307 * stdout and stderr
3308 */
3309
3310static PyObject *
3311os2emx_popen3(PyObject *self, PyObject *args)
3312{
3313 PyObject *f;
3314 int tm = 0;
3315
3316 char *cmdstring;
3317 char *mode = "t";
3318 int bufsize = -1;
3319 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3320 return NULL;
3321
3322 if (*mode == 't')
3323 tm = O_TEXT;
3324 else if (*mode != 'b') {
3325 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3326 return NULL;
3327 } else
3328 tm = O_BINARY;
3329
3330 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3331
3332 return f;
3333}
3334
3335/*
3336 * Variation on os2emx.popen2
3337 *
3338 * The result of this function is 2 pipes - the processes stdin,
3339 * and stdout+stderr combined as a single pipe.
3340 */
3341
3342static PyObject *
3343os2emx_popen4(PyObject *self, PyObject *args)
3344{
3345 PyObject *f;
3346 int tm = 0;
3347
3348 char *cmdstring;
3349 char *mode = "t";
3350 int bufsize = -1;
3351 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3352 return NULL;
3353
3354 if (*mode == 't')
3355 tm = O_TEXT;
3356 else if (*mode != 'b') {
3357 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3358 return NULL;
3359 } else
3360 tm = O_BINARY;
3361
3362 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3363
3364 return f;
3365}
3366
3367/* a couple of structures for convenient handling of multiple
3368 * file handles and pipes
3369 */
3370struct file_ref
3371{
3372 int handle;
3373 int flags;
3374};
3375
3376struct pipe_ref
3377{
3378 int rd;
3379 int wr;
3380};
3381
3382/* The following code is derived from the win32 code */
3383
3384static PyObject *
3385_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3386{
3387 struct file_ref stdio[3];
3388 struct pipe_ref p_fd[3];
3389 FILE *p_s[3];
3390 int file_count, i, pipe_err, pipe_pid;
3391 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3392 PyObject *f, *p_f[3];
3393
3394 /* file modes for subsequent fdopen's on pipe handles */
3395 if (mode == O_TEXT)
3396 {
3397 rd_mode = "rt";
3398 wr_mode = "wt";
3399 }
3400 else
3401 {
3402 rd_mode = "rb";
3403 wr_mode = "wb";
3404 }
3405
3406 /* prepare shell references */
3407 if ((shell = getenv("EMXSHELL")) == NULL)
3408 if ((shell = getenv("COMSPEC")) == NULL)
3409 {
3410 errno = ENOENT;
3411 return posix_error();
3412 }
3413
3414 sh_name = _getname(shell);
3415 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3416 opt = "/c";
3417 else
3418 opt = "-c";
3419
3420 /* save current stdio fds + their flags, and set not inheritable */
3421 i = pipe_err = 0;
3422 while (pipe_err >= 0 && i < 3)
3423 {
3424 pipe_err = stdio[i].handle = dup(i);
3425 stdio[i].flags = fcntl(i, F_GETFD, 0);
3426 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3427 i++;
3428 }
3429 if (pipe_err < 0)
3430 {
3431 /* didn't get them all saved - clean up and bail out */
3432 int saved_err = errno;
3433 while (i-- > 0)
3434 {
3435 close(stdio[i].handle);
3436 }
3437 errno = saved_err;
3438 return posix_error();
3439 }
3440
3441 /* create pipe ends */
3442 file_count = 2;
3443 if (n == POPEN_3)
3444 file_count = 3;
3445 i = pipe_err = 0;
3446 while ((pipe_err == 0) && (i < file_count))
3447 pipe_err = pipe((int *)&p_fd[i++]);
3448 if (pipe_err < 0)
3449 {
3450 /* didn't get them all made - clean up and bail out */
3451 while (i-- > 0)
3452 {
3453 close(p_fd[i].wr);
3454 close(p_fd[i].rd);
3455 }
3456 errno = EPIPE;
3457 return posix_error();
3458 }
3459
3460 /* change the actual standard IO streams over temporarily,
3461 * making the retained pipe ends non-inheritable
3462 */
3463 pipe_err = 0;
3464
3465 /* - stdin */
3466 if (dup2(p_fd[0].rd, 0) == 0)
3467 {
3468 close(p_fd[0].rd);
3469 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3470 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3471 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3472 {
3473 close(p_fd[0].wr);
3474 pipe_err = -1;
3475 }
3476 }
3477 else
3478 {
3479 pipe_err = -1;
3480 }
3481
3482 /* - stdout */
3483 if (pipe_err == 0)
3484 {
3485 if (dup2(p_fd[1].wr, 1) == 1)
3486 {
3487 close(p_fd[1].wr);
3488 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3489 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3490 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3491 {
3492 close(p_fd[1].rd);
3493 pipe_err = -1;
3494 }
3495 }
3496 else
3497 {
3498 pipe_err = -1;
3499 }
3500 }
3501
3502 /* - stderr, as required */
3503 if (pipe_err == 0)
3504 switch (n)
3505 {
3506 case POPEN_3:
3507 {
3508 if (dup2(p_fd[2].wr, 2) == 2)
3509 {
3510 close(p_fd[2].wr);
3511 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3512 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3513 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3514 {
3515 close(p_fd[2].rd);
3516 pipe_err = -1;
3517 }
3518 }
3519 else
3520 {
3521 pipe_err = -1;
3522 }
3523 break;
3524 }
3525
3526 case POPEN_4:
3527 {
3528 if (dup2(1, 2) != 2)
3529 {
3530 pipe_err = -1;
3531 }
3532 break;
3533 }
3534 }
3535
3536 /* spawn the child process */
3537 if (pipe_err == 0)
3538 {
3539 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3540 if (pipe_pid == -1)
3541 {
3542 pipe_err = -1;
3543 }
3544 else
3545 {
3546 /* save the PID into the FILE structure
3547 * NOTE: this implementation doesn't actually
3548 * take advantage of this, but do it for
3549 * completeness - AIM Apr01
3550 */
3551 for (i = 0; i < file_count; i++)
3552 p_s[i]->_pid = pipe_pid;
3553 }
3554 }
3555
3556 /* reset standard IO to normal */
3557 for (i = 0; i < 3; i++)
3558 {
3559 dup2(stdio[i].handle, i);
3560 fcntl(i, F_SETFD, stdio[i].flags);
3561 close(stdio[i].handle);
3562 }
3563
3564 /* if any remnant problems, clean up and bail out */
3565 if (pipe_err < 0)
3566 {
3567 for (i = 0; i < 3; i++)
3568 {
3569 close(p_fd[i].rd);
3570 close(p_fd[i].wr);
3571 }
3572 errno = EPIPE;
3573 return posix_error_with_filename(cmdstring);
3574 }
3575
3576 /* build tuple of file objects to return */
3577 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3578 PyFile_SetBufSize(p_f[0], bufsize);
3579 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3580 PyFile_SetBufSize(p_f[1], bufsize);
3581 if (n == POPEN_3)
3582 {
3583 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3584 PyFile_SetBufSize(p_f[0], bufsize);
3585 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3586 }
3587 else
3588 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3589
3590 /*
3591 * Insert the files we've created into the process dictionary
3592 * all referencing the list with the process handle and the
3593 * initial number of files (see description below in _PyPclose).
3594 * Since if _PyPclose later tried to wait on a process when all
3595 * handles weren't closed, it could create a deadlock with the
3596 * child, we spend some energy here to try to ensure that we
3597 * either insert all file handles into the dictionary or none
3598 * at all. It's a little clumsy with the various popen modes
3599 * and variable number of files involved.
3600 */
3601 if (!_PyPopenProcs)
3602 {
3603 _PyPopenProcs = PyDict_New();
3604 }
3605
3606 if (_PyPopenProcs)
3607 {
3608 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3609 int ins_rc[3];
3610
3611 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3612 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3613
3614 procObj = PyList_New(2);
3615 pidObj = PyInt_FromLong((long) pipe_pid);
3616 intObj = PyInt_FromLong((long) file_count);
3617
3618 if (procObj && pidObj && intObj)
3619 {
3620 PyList_SetItem(procObj, 0, pidObj);
3621 PyList_SetItem(procObj, 1, intObj);
3622
3623 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3624 if (fileObj[0])
3625 {
3626 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3627 fileObj[0],
3628 procObj);
3629 }
3630 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3631 if (fileObj[1])
3632 {
3633 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3634 fileObj[1],
3635 procObj);
3636 }
3637 if (file_count >= 3)
3638 {
3639 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3640 if (fileObj[2])
3641 {
3642 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3643 fileObj[2],
3644 procObj);
3645 }
3646 }
3647
3648 if (ins_rc[0] < 0 || !fileObj[0] ||
3649 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3650 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3651 {
3652 /* Something failed - remove any dictionary
3653 * entries that did make it.
3654 */
3655 if (!ins_rc[0] && fileObj[0])
3656 {
3657 PyDict_DelItem(_PyPopenProcs,
3658 fileObj[0]);
3659 }
3660 if (!ins_rc[1] && fileObj[1])
3661 {
3662 PyDict_DelItem(_PyPopenProcs,
3663 fileObj[1]);
3664 }
3665 if (!ins_rc[2] && fileObj[2])
3666 {
3667 PyDict_DelItem(_PyPopenProcs,
3668 fileObj[2]);
3669 }
3670 }
3671 }
3672
3673 /*
3674 * Clean up our localized references for the dictionary keys
3675 * and value since PyDict_SetItem will Py_INCREF any copies
3676 * that got placed in the dictionary.
3677 */
3678 Py_XDECREF(procObj);
3679 Py_XDECREF(fileObj[0]);
3680 Py_XDECREF(fileObj[1]);
3681 Py_XDECREF(fileObj[2]);
3682 }
3683
3684 /* Child is launched. */
3685 return f;
3686}
3687
3688/*
3689 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3690 * exit code for the child process and return as a result of the close.
3691 *
3692 * This function uses the _PyPopenProcs dictionary in order to map the
3693 * input file pointer to information about the process that was
3694 * originally created by the popen* call that created the file pointer.
3695 * The dictionary uses the file pointer as a key (with one entry
3696 * inserted for each file returned by the original popen* call) and a
3697 * single list object as the value for all files from a single call.
3698 * The list object contains the Win32 process handle at [0], and a file
3699 * count at [1], which is initialized to the total number of file
3700 * handles using that list.
3701 *
3702 * This function closes whichever handle it is passed, and decrements
3703 * the file count in the dictionary for the process handle pointed to
3704 * by this file. On the last close (when the file count reaches zero),
3705 * this function will wait for the child process and then return its
3706 * exit code as the result of the close() operation. This permits the
3707 * files to be closed in any order - it is always the close() of the
3708 * final handle that will return the exit code.
3709 */
3710
3711 /* RED_FLAG 31-Aug-2000 Tim
3712 * This is always called (today!) between a pair of
3713 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3714 * macros. So the thread running this has no valid thread state, as
3715 * far as Python is concerned. However, this calls some Python API
3716 * functions that cannot be called safely without a valid thread
3717 * state, in particular PyDict_GetItem.
3718 * As a temporary hack (although it may last for years ...), we
3719 * *rely* on not having a valid thread state in this function, in
3720 * order to create our own "from scratch".
3721 * This will deadlock if _PyPclose is ever called by a thread
3722 * holding the global lock.
3723 * (The OS/2 EMX thread support appears to cover the case where the
3724 * lock is already held - AIM Apr01)
3725 */
3726
3727static int _PyPclose(FILE *file)
3728{
3729 int result;
3730 int exit_code;
3731 int pipe_pid;
3732 PyObject *procObj, *pidObj, *intObj, *fileObj;
3733 int file_count;
3734#ifdef WITH_THREAD
3735 PyInterpreterState* pInterpreterState;
3736 PyThreadState* pThreadState;
3737#endif
3738
3739 /* Close the file handle first, to ensure it can't block the
3740 * child from exiting if it's the last handle.
3741 */
3742 result = fclose(file);
3743
3744#ifdef WITH_THREAD
3745 /* Bootstrap a valid thread state into existence. */
3746 pInterpreterState = PyInterpreterState_New();
3747 if (!pInterpreterState) {
3748 /* Well, we're hosed now! We don't have a thread
3749 * state, so can't call a nice error routine, or raise
3750 * an exception. Just die.
3751 */
3752 Py_FatalError("unable to allocate interpreter state "
3753 "when closing popen object.");
3754 return -1; /* unreachable */
3755 }
3756 pThreadState = PyThreadState_New(pInterpreterState);
3757 if (!pThreadState) {
3758 Py_FatalError("unable to allocate thread state "
3759 "when closing popen object.");
3760 return -1; /* unreachable */
3761 }
3762 /* Grab the global lock. Note that this will deadlock if the
3763 * current thread already has the lock! (see RED_FLAG comments
3764 * before this function)
3765 */
3766 PyEval_RestoreThread(pThreadState);
3767#endif
3768
3769 if (_PyPopenProcs)
3770 {
3771 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3772 (procObj = PyDict_GetItem(_PyPopenProcs,
3773 fileObj)) != NULL &&
3774 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3775 (intObj = PyList_GetItem(procObj,1)) != NULL)
3776 {
3777 pipe_pid = (int) PyInt_AsLong(pidObj);
3778 file_count = (int) PyInt_AsLong(intObj);
3779
3780 if (file_count > 1)
3781 {
3782 /* Still other files referencing process */
3783 file_count--;
3784 PyList_SetItem(procObj,1,
3785 PyInt_FromLong((long) file_count));
3786 }
3787 else
3788 {
3789 /* Last file for this process */
3790 if (result != EOF &&
3791 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3792 {
3793 /* extract exit status */
3794 if (WIFEXITED(exit_code))
3795 {
3796 result = WEXITSTATUS(exit_code);
3797 }
3798 else
3799 {
3800 errno = EPIPE;
3801 result = -1;
3802 }
3803 }
3804 else
3805 {
3806 /* Indicate failure - this will cause the file object
3807 * to raise an I/O error and translate the last
3808 * error code from errno. We do have a problem with
3809 * last errors that overlap the normal errno table,
3810 * but that's a consistent problem with the file object.
3811 */
3812 result = -1;
3813 }
3814 }
3815
3816 /* Remove this file pointer from dictionary */
3817 PyDict_DelItem(_PyPopenProcs, fileObj);
3818
3819 if (PyDict_Size(_PyPopenProcs) == 0)
3820 {
3821 Py_DECREF(_PyPopenProcs);
3822 _PyPopenProcs = NULL;
3823 }
3824
3825 } /* if object retrieval ok */
3826
3827 Py_XDECREF(fileObj);
3828 } /* if _PyPopenProcs */
3829
3830#ifdef WITH_THREAD
3831 /* Tear down the thread & interpreter states.
3832 * Note that interpreter state clear & delete functions automatically
3833 * call the thread clear & delete functions, and indeed insist on
3834 * doing that themselves. The lock must be held during the clear, but
3835 * need not be held during the delete.
3836 */
3837 PyInterpreterState_Clear(pInterpreterState);
3838 PyEval_ReleaseThread(pThreadState);
3839 PyInterpreterState_Delete(pInterpreterState);
3840#endif
3841
3842 return result;
3843}
3844
3845#endif /* PYCC_??? */
3846
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003847#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848
3849/*
3850 * Portable 'popen' replacement for Win32.
3851 *
3852 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3853 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003854 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 */
3856
3857#include <malloc.h>
3858#include <io.h>
3859#include <fcntl.h>
3860
3861/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3862#define POPEN_1 1
3863#define POPEN_2 2
3864#define POPEN_3 3
3865#define POPEN_4 4
3866
3867static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003868static int _PyPclose(FILE *file);
3869
3870/*
3871 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003872 * for use when retrieving the process exit code. See _PyPclose() below
3873 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003874 */
3875static PyObject *_PyPopenProcs = NULL;
3876
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003877
3878/* popen that works from a GUI.
3879 *
3880 * The result of this function is a pipe (file) connected to the
3881 * processes stdin or stdout, depending on the requested mode.
3882 */
3883
3884static PyObject *
3885posix_popen(PyObject *self, PyObject *args)
3886{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003887 PyObject *f, *s;
3888 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003889
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003890 char *cmdstring;
3891 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003892 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003893 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003894 return NULL;
3895
3896 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003897
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003898 if (*mode == 'r')
3899 tm = _O_RDONLY;
3900 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003901 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 return NULL;
3903 } else
3904 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003905
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003906 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003907 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003908 return NULL;
3909 }
3910
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003911 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003912 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003913 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003914 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003915 else
3916 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3917
3918 return f;
3919}
3920
3921/* Variation on win32pipe.popen
3922 *
3923 * The result of this function is a pipe (file) connected to the
3924 * process's stdin, and a pipe connected to the process's stdout.
3925 */
3926
3927static PyObject *
3928win32_popen2(PyObject *self, PyObject *args)
3929{
3930 PyObject *f;
3931 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003932
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003933 char *cmdstring;
3934 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003935 int bufsize = -1;
3936 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003937 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003938
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003939 if (*mode == 't')
3940 tm = _O_TEXT;
3941 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003942 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003943 return NULL;
3944 } else
3945 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003946
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003947 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003948 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003949 return NULL;
3950 }
3951
3952 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003953
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003954 return f;
3955}
3956
3957/*
3958 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003959 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003960 * The result of this function is 3 pipes - the process's stdin,
3961 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003962 */
3963
3964static PyObject *
3965win32_popen3(PyObject *self, PyObject *args)
3966{
3967 PyObject *f;
3968 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003969
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003970 char *cmdstring;
3971 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003972 int bufsize = -1;
3973 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003975
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003976 if (*mode == 't')
3977 tm = _O_TEXT;
3978 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003979 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003980 return NULL;
3981 } else
3982 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003983
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003984 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003985 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003986 return NULL;
3987 }
3988
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003989 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003990
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003991 return f;
3992}
3993
3994/*
3995 * Variation on win32pipe.popen
3996 *
Tim Peters5aa91602002-01-30 05:46:57 +00003997 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003998 * and stdout+stderr combined as a single pipe.
3999 */
4000
4001static PyObject *
4002win32_popen4(PyObject *self, PyObject *args)
4003{
4004 PyObject *f;
4005 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004006
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004007 char *cmdstring;
4008 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004009 int bufsize = -1;
4010 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004011 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004012
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004013 if (*mode == 't')
4014 tm = _O_TEXT;
4015 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004016 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004017 return NULL;
4018 } else
4019 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004020
4021 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004022 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004023 return NULL;
4024 }
4025
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004026 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004027
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004028 return f;
4029}
4030
Mark Hammond08501372001-01-31 07:30:29 +00004031static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004032_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004033 HANDLE hStdin,
4034 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004035 HANDLE hStderr,
4036 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004037{
4038 PROCESS_INFORMATION piProcInfo;
4039 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004040 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004041 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004042 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004043 int i;
4044 int x;
4045
4046 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004047 char *comshell;
4048
Tim Peters92e4dd82002-10-05 01:47:34 +00004049 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004050 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4051 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004052
4053 /* Explicitly check if we are using COMMAND.COM. If we are
4054 * then use the w9xpopen hack.
4055 */
4056 comshell = s1 + x;
4057 while (comshell >= s1 && *comshell != '\\')
4058 --comshell;
4059 ++comshell;
4060
4061 if (GetVersion() < 0x80000000 &&
4062 _stricmp(comshell, "command.com") != 0) {
4063 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004064 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004065 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004066 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004067 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004068 }
4069 else {
4070 /*
Tim Peters402d5982001-08-27 06:37:48 +00004071 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4072 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004073 */
Mark Hammond08501372001-01-31 07:30:29 +00004074 char modulepath[_MAX_PATH];
4075 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004076 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4077 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004078 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004079 x = i+1;
4080 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004081 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004082 strncat(modulepath,
4083 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004084 (sizeof(modulepath)/sizeof(modulepath[0]))
4085 -strlen(modulepath));
4086 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004087 /* Eeek - file-not-found - possibly an embedding
4088 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004089 */
Tim Peters5aa91602002-01-30 05:46:57 +00004090 strncpy(modulepath,
4091 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004092 sizeof(modulepath)/sizeof(modulepath[0]));
4093 if (modulepath[strlen(modulepath)-1] != '\\')
4094 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004095 strncat(modulepath,
4096 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004097 (sizeof(modulepath)/sizeof(modulepath[0]))
4098 -strlen(modulepath));
4099 /* No where else to look - raise an easily identifiable
4100 error, rather than leaving Windows to report
4101 "file not found" - as the user is probably blissfully
4102 unaware this shim EXE is used, and it will confuse them.
4103 (well, it confused me for a while ;-)
4104 */
4105 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004106 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004107 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004108 "for popen to work with your shell "
4109 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004110 szConsoleSpawn);
4111 return FALSE;
4112 }
4113 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004114 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004115 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004116 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004117
Tim Peters92e4dd82002-10-05 01:47:34 +00004118 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004119 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004120 /* To maintain correct argument passing semantics,
4121 we pass the command-line as it stands, and allow
4122 quoting to be applied. w9xpopen.exe will then
4123 use its argv vector, and re-quote the necessary
4124 args for the ultimate child process.
4125 */
Tim Peters75cdad52001-11-28 22:07:30 +00004126 PyOS_snprintf(
4127 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004128 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004129 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004130 s1,
4131 s3,
4132 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004133 /* Not passing CREATE_NEW_CONSOLE has been known to
4134 cause random failures on win9x. Specifically a
4135 dialog:
4136 "Your program accessed mem currently in use at xxx"
4137 and a hopeful warning about the stability of your
4138 system.
4139 Cost is Ctrl+C wont kill children, but anyone
4140 who cares can have a go!
4141 */
4142 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004143 }
4144 }
4145
4146 /* Could be an else here to try cmd.exe / command.com in the path
4147 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004148 else {
Tim Peters402d5982001-08-27 06:37:48 +00004149 PyErr_SetString(PyExc_RuntimeError,
4150 "Cannot locate a COMSPEC environment variable to "
4151 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004152 return FALSE;
4153 }
Tim Peters5aa91602002-01-30 05:46:57 +00004154
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004155 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4156 siStartInfo.cb = sizeof(STARTUPINFO);
4157 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4158 siStartInfo.hStdInput = hStdin;
4159 siStartInfo.hStdOutput = hStdout;
4160 siStartInfo.hStdError = hStderr;
4161 siStartInfo.wShowWindow = SW_HIDE;
4162
4163 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004164 s2,
4165 NULL,
4166 NULL,
4167 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004168 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004169 NULL,
4170 NULL,
4171 &siStartInfo,
4172 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004174 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004175
Mark Hammondb37a3732000-08-14 04:47:33 +00004176 /* Return process handle */
4177 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004178 return TRUE;
4179 }
Tim Peters402d5982001-08-27 06:37:48 +00004180 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004181 return FALSE;
4182}
4183
4184/* The following code is based off of KB: Q190351 */
4185
4186static PyObject *
4187_PyPopen(char *cmdstring, int mode, int n)
4188{
4189 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4190 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004191 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004192
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004193 SECURITY_ATTRIBUTES saAttr;
4194 BOOL fSuccess;
4195 int fd1, fd2, fd3;
4196 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004197 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004198 PyObject *f;
4199
4200 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4201 saAttr.bInheritHandle = TRUE;
4202 saAttr.lpSecurityDescriptor = NULL;
4203
4204 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4205 return win32_error("CreatePipe", NULL);
4206
4207 /* Create new output read handle and the input write handle. Set
4208 * the inheritance properties to FALSE. Otherwise, the child inherits
4209 * the these handles; resulting in non-closeable handles to the pipes
4210 * being created. */
4211 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004212 GetCurrentProcess(), &hChildStdinWrDup, 0,
4213 FALSE,
4214 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004215 if (!fSuccess)
4216 return win32_error("DuplicateHandle", NULL);
4217
4218 /* Close the inheritable version of ChildStdin
4219 that we're using. */
4220 CloseHandle(hChildStdinWr);
4221
4222 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4223 return win32_error("CreatePipe", NULL);
4224
4225 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004226 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4227 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004228 if (!fSuccess)
4229 return win32_error("DuplicateHandle", NULL);
4230
4231 /* Close the inheritable version of ChildStdout
4232 that we're using. */
4233 CloseHandle(hChildStdoutRd);
4234
4235 if (n != POPEN_4) {
4236 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4237 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004238 fSuccess = DuplicateHandle(GetCurrentProcess(),
4239 hChildStderrRd,
4240 GetCurrentProcess(),
4241 &hChildStderrRdDup, 0,
4242 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 if (!fSuccess)
4244 return win32_error("DuplicateHandle", NULL);
4245 /* Close the inheritable version of ChildStdErr that we're using. */
4246 CloseHandle(hChildStderrRd);
4247 }
Tim Peters5aa91602002-01-30 05:46:57 +00004248
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004249 switch (n) {
4250 case POPEN_1:
4251 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4252 case _O_WRONLY | _O_TEXT:
4253 /* Case for writing to child Stdin in text mode. */
4254 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4255 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004256 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004257 PyFile_SetBufSize(f, 0);
4258 /* We don't care about these pipes anymore, so close them. */
4259 CloseHandle(hChildStdoutRdDup);
4260 CloseHandle(hChildStderrRdDup);
4261 break;
4262
4263 case _O_RDONLY | _O_TEXT:
4264 /* Case for reading from child Stdout in text mode. */
4265 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4266 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004267 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004268 PyFile_SetBufSize(f, 0);
4269 /* We don't care about these pipes anymore, so close them. */
4270 CloseHandle(hChildStdinWrDup);
4271 CloseHandle(hChildStderrRdDup);
4272 break;
4273
4274 case _O_RDONLY | _O_BINARY:
4275 /* Case for readinig from child Stdout in binary mode. */
4276 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4277 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004278 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004279 PyFile_SetBufSize(f, 0);
4280 /* We don't care about these pipes anymore, so close them. */
4281 CloseHandle(hChildStdinWrDup);
4282 CloseHandle(hChildStderrRdDup);
4283 break;
4284
4285 case _O_WRONLY | _O_BINARY:
4286 /* Case for writing to child Stdin in binary mode. */
4287 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4288 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004289 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004290 PyFile_SetBufSize(f, 0);
4291 /* We don't care about these pipes anymore, so close them. */
4292 CloseHandle(hChildStdoutRdDup);
4293 CloseHandle(hChildStderrRdDup);
4294 break;
4295 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004296 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004297 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004298
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004299 case POPEN_2:
4300 case POPEN_4:
4301 {
4302 char *m1, *m2;
4303 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004304
Tim Peters7dca21e2002-08-19 00:42:29 +00004305 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004306 m1 = "r";
4307 m2 = "w";
4308 } else {
4309 m1 = "rb";
4310 m2 = "wb";
4311 }
4312
4313 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4314 f1 = _fdopen(fd1, m2);
4315 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4316 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004317 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004319 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004320 PyFile_SetBufSize(p2, 0);
4321
4322 if (n != 4)
4323 CloseHandle(hChildStderrRdDup);
4324
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004325 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004326 Py_XDECREF(p1);
4327 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004328 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004329 break;
4330 }
Tim Peters5aa91602002-01-30 05:46:57 +00004331
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004332 case POPEN_3:
4333 {
4334 char *m1, *m2;
4335 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004336
Tim Peters7dca21e2002-08-19 00:42:29 +00004337 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 m1 = "r";
4339 m2 = "w";
4340 } else {
4341 m1 = "rb";
4342 m2 = "wb";
4343 }
4344
4345 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4346 f1 = _fdopen(fd1, m2);
4347 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4348 f2 = _fdopen(fd2, m1);
4349 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4350 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004351 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004352 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4353 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354 PyFile_SetBufSize(p1, 0);
4355 PyFile_SetBufSize(p2, 0);
4356 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004357 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004358 Py_XDECREF(p1);
4359 Py_XDECREF(p2);
4360 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004361 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004362 break;
4363 }
4364 }
4365
4366 if (n == POPEN_4) {
4367 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004368 hChildStdinRd,
4369 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004370 hChildStdoutWr,
4371 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004372 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004373 }
4374 else {
4375 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004376 hChildStdinRd,
4377 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004378 hChildStderrWr,
4379 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004380 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004381 }
4382
Mark Hammondb37a3732000-08-14 04:47:33 +00004383 /*
4384 * Insert the files we've created into the process dictionary
4385 * all referencing the list with the process handle and the
4386 * initial number of files (see description below in _PyPclose).
4387 * Since if _PyPclose later tried to wait on a process when all
4388 * handles weren't closed, it could create a deadlock with the
4389 * child, we spend some energy here to try to ensure that we
4390 * either insert all file handles into the dictionary or none
4391 * at all. It's a little clumsy with the various popen modes
4392 * and variable number of files involved.
4393 */
4394 if (!_PyPopenProcs) {
4395 _PyPopenProcs = PyDict_New();
4396 }
4397
4398 if (_PyPopenProcs) {
4399 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4400 int ins_rc[3];
4401
4402 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4403 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4404
4405 procObj = PyList_New(2);
4406 hProcessObj = PyLong_FromVoidPtr(hProcess);
4407 intObj = PyInt_FromLong(file_count);
4408
4409 if (procObj && hProcessObj && intObj) {
4410 PyList_SetItem(procObj,0,hProcessObj);
4411 PyList_SetItem(procObj,1,intObj);
4412
4413 fileObj[0] = PyLong_FromVoidPtr(f1);
4414 if (fileObj[0]) {
4415 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4416 fileObj[0],
4417 procObj);
4418 }
4419 if (file_count >= 2) {
4420 fileObj[1] = PyLong_FromVoidPtr(f2);
4421 if (fileObj[1]) {
4422 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4423 fileObj[1],
4424 procObj);
4425 }
4426 }
4427 if (file_count >= 3) {
4428 fileObj[2] = PyLong_FromVoidPtr(f3);
4429 if (fileObj[2]) {
4430 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4431 fileObj[2],
4432 procObj);
4433 }
4434 }
4435
4436 if (ins_rc[0] < 0 || !fileObj[0] ||
4437 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4438 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4439 /* Something failed - remove any dictionary
4440 * entries that did make it.
4441 */
4442 if (!ins_rc[0] && fileObj[0]) {
4443 PyDict_DelItem(_PyPopenProcs,
4444 fileObj[0]);
4445 }
4446 if (!ins_rc[1] && fileObj[1]) {
4447 PyDict_DelItem(_PyPopenProcs,
4448 fileObj[1]);
4449 }
4450 if (!ins_rc[2] && fileObj[2]) {
4451 PyDict_DelItem(_PyPopenProcs,
4452 fileObj[2]);
4453 }
4454 }
4455 }
Tim Peters5aa91602002-01-30 05:46:57 +00004456
Mark Hammondb37a3732000-08-14 04:47:33 +00004457 /*
4458 * Clean up our localized references for the dictionary keys
4459 * and value since PyDict_SetItem will Py_INCREF any copies
4460 * that got placed in the dictionary.
4461 */
4462 Py_XDECREF(procObj);
4463 Py_XDECREF(fileObj[0]);
4464 Py_XDECREF(fileObj[1]);
4465 Py_XDECREF(fileObj[2]);
4466 }
4467
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004468 /* Child is launched. Close the parents copy of those pipe
4469 * handles that only the child should have open. You need to
4470 * make sure that no handles to the write end of the output pipe
4471 * are maintained in this process or else the pipe will not close
4472 * when the child process exits and the ReadFile will hang. */
4473
4474 if (!CloseHandle(hChildStdinRd))
4475 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004476
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004477 if (!CloseHandle(hChildStdoutWr))
4478 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004479
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004480 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4481 return win32_error("CloseHandle", NULL);
4482
4483 return f;
4484}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004485
4486/*
4487 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4488 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004489 *
4490 * This function uses the _PyPopenProcs dictionary in order to map the
4491 * input file pointer to information about the process that was
4492 * originally created by the popen* call that created the file pointer.
4493 * The dictionary uses the file pointer as a key (with one entry
4494 * inserted for each file returned by the original popen* call) and a
4495 * single list object as the value for all files from a single call.
4496 * The list object contains the Win32 process handle at [0], and a file
4497 * count at [1], which is initialized to the total number of file
4498 * handles using that list.
4499 *
4500 * This function closes whichever handle it is passed, and decrements
4501 * the file count in the dictionary for the process handle pointed to
4502 * by this file. On the last close (when the file count reaches zero),
4503 * this function will wait for the child process and then return its
4504 * exit code as the result of the close() operation. This permits the
4505 * files to be closed in any order - it is always the close() of the
4506 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004507 */
Tim Peters736aa322000-09-01 06:51:24 +00004508
4509 /* RED_FLAG 31-Aug-2000 Tim
4510 * This is always called (today!) between a pair of
4511 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4512 * macros. So the thread running this has no valid thread state, as
4513 * far as Python is concerned. However, this calls some Python API
4514 * functions that cannot be called safely without a valid thread
4515 * state, in particular PyDict_GetItem.
4516 * As a temporary hack (although it may last for years ...), we
4517 * *rely* on not having a valid thread state in this function, in
4518 * order to create our own "from scratch".
4519 * This will deadlock if _PyPclose is ever called by a thread
4520 * holding the global lock.
4521 */
4522
Fredrik Lundh56055a42000-07-23 19:47:12 +00004523static int _PyPclose(FILE *file)
4524{
Fredrik Lundh20318932000-07-26 17:29:12 +00004525 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004526 DWORD exit_code;
4527 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004528 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4529 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004530#ifdef WITH_THREAD
4531 PyInterpreterState* pInterpreterState;
4532 PyThreadState* pThreadState;
4533#endif
4534
Fredrik Lundh20318932000-07-26 17:29:12 +00004535 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004536 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004537 */
4538 result = fclose(file);
4539
Tim Peters736aa322000-09-01 06:51:24 +00004540#ifdef WITH_THREAD
4541 /* Bootstrap a valid thread state into existence. */
4542 pInterpreterState = PyInterpreterState_New();
4543 if (!pInterpreterState) {
4544 /* Well, we're hosed now! We don't have a thread
4545 * state, so can't call a nice error routine, or raise
4546 * an exception. Just die.
4547 */
4548 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004549 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004550 return -1; /* unreachable */
4551 }
4552 pThreadState = PyThreadState_New(pInterpreterState);
4553 if (!pThreadState) {
4554 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004555 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004556 return -1; /* unreachable */
4557 }
4558 /* Grab the global lock. Note that this will deadlock if the
4559 * current thread already has the lock! (see RED_FLAG comments
4560 * before this function)
4561 */
4562 PyEval_RestoreThread(pThreadState);
4563#endif
4564
Fredrik Lundh56055a42000-07-23 19:47:12 +00004565 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004566 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4567 (procObj = PyDict_GetItem(_PyPopenProcs,
4568 fileObj)) != NULL &&
4569 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4570 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4571
4572 hProcess = PyLong_AsVoidPtr(hProcessObj);
4573 file_count = PyInt_AsLong(intObj);
4574
4575 if (file_count > 1) {
4576 /* Still other files referencing process */
4577 file_count--;
4578 PyList_SetItem(procObj,1,
4579 PyInt_FromLong(file_count));
4580 } else {
4581 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004582 if (result != EOF &&
4583 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4584 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004585 /* Possible truncation here in 16-bit environments, but
4586 * real exit codes are just the lower byte in any event.
4587 */
4588 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004589 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004590 /* Indicate failure - this will cause the file object
4591 * to raise an I/O error and translate the last Win32
4592 * error code from errno. We do have a problem with
4593 * last errors that overlap the normal errno table,
4594 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004595 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004596 if (result != EOF) {
4597 /* If the error wasn't from the fclose(), then
4598 * set errno for the file object error handling.
4599 */
4600 errno = GetLastError();
4601 }
4602 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004603 }
4604
4605 /* Free up the native handle at this point */
4606 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004607 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004608
Mark Hammondb37a3732000-08-14 04:47:33 +00004609 /* Remove this file pointer from dictionary */
4610 PyDict_DelItem(_PyPopenProcs, fileObj);
4611
4612 if (PyDict_Size(_PyPopenProcs) == 0) {
4613 Py_DECREF(_PyPopenProcs);
4614 _PyPopenProcs = NULL;
4615 }
4616
4617 } /* if object retrieval ok */
4618
4619 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004620 } /* if _PyPopenProcs */
4621
Tim Peters736aa322000-09-01 06:51:24 +00004622#ifdef WITH_THREAD
4623 /* Tear down the thread & interpreter states.
4624 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004625 * call the thread clear & delete functions, and indeed insist on
4626 * doing that themselves. The lock must be held during the clear, but
4627 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004628 */
4629 PyInterpreterState_Clear(pInterpreterState);
4630 PyEval_ReleaseThread(pThreadState);
4631 PyInterpreterState_Delete(pInterpreterState);
4632#endif
4633
Fredrik Lundh56055a42000-07-23 19:47:12 +00004634 return result;
4635}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004636
4637#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004639posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004640{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004641 char *name;
4642 char *mode = "r";
4643 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004644 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004645 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004646 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004647 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004648 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004649 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004650 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004651 if (fp == NULL)
4652 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004653 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004654 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004655 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004656 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004657}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004658
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004659#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004660#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004662
Guido van Rossumb6775db1994-08-01 11:34:53 +00004663#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004665"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666Set the current process's user id.");
4667
Barry Warsaw53699e91996-12-10 23:23:01 +00004668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004669posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004670{
4671 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004672 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004673 return NULL;
4674 if (setuid(uid) < 0)
4675 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004676 Py_INCREF(Py_None);
4677 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004678}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004679#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004681
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004682#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004684"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685Set the current process's effective user id.");
4686
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004687static PyObject *
4688posix_seteuid (PyObject *self, PyObject *args)
4689{
4690 int euid;
4691 if (!PyArg_ParseTuple(args, "i", &euid)) {
4692 return NULL;
4693 } else if (seteuid(euid) < 0) {
4694 return posix_error();
4695 } else {
4696 Py_INCREF(Py_None);
4697 return Py_None;
4698 }
4699}
4700#endif /* HAVE_SETEUID */
4701
4702#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004704"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705Set the current process's effective group id.");
4706
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004707static PyObject *
4708posix_setegid (PyObject *self, PyObject *args)
4709{
4710 int egid;
4711 if (!PyArg_ParseTuple(args, "i", &egid)) {
4712 return NULL;
4713 } else if (setegid(egid) < 0) {
4714 return posix_error();
4715 } else {
4716 Py_INCREF(Py_None);
4717 return Py_None;
4718 }
4719}
4720#endif /* HAVE_SETEGID */
4721
4722#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004723PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004724"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004725Set the current process's real and effective user ids.");
4726
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004727static PyObject *
4728posix_setreuid (PyObject *self, PyObject *args)
4729{
4730 int ruid, euid;
4731 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4732 return NULL;
4733 } else if (setreuid(ruid, euid) < 0) {
4734 return posix_error();
4735 } else {
4736 Py_INCREF(Py_None);
4737 return Py_None;
4738 }
4739}
4740#endif /* HAVE_SETREUID */
4741
4742#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004743PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004744"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745Set the current process's real and effective group ids.");
4746
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004747static PyObject *
4748posix_setregid (PyObject *self, PyObject *args)
4749{
4750 int rgid, egid;
4751 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4752 return NULL;
4753 } else if (setregid(rgid, egid) < 0) {
4754 return posix_error();
4755 } else {
4756 Py_INCREF(Py_None);
4757 return Py_None;
4758 }
4759}
4760#endif /* HAVE_SETREGID */
4761
Guido van Rossumb6775db1994-08-01 11:34:53 +00004762#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004763PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004764"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004765Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004766
Barry Warsaw53699e91996-12-10 23:23:01 +00004767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004768posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004769{
4770 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004771 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004772 return NULL;
4773 if (setgid(gid) < 0)
4774 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004775 Py_INCREF(Py_None);
4776 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004777}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004778#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004779
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004780#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004782"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004784
4785static PyObject *
4786posix_setgroups(PyObject *self, PyObject *args)
4787{
4788 PyObject *groups;
4789 int i, len;
4790 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004791
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004792 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4793 return NULL;
4794 if (!PySequence_Check(groups)) {
4795 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4796 return NULL;
4797 }
4798 len = PySequence_Size(groups);
4799 if (len > MAX_GROUPS) {
4800 PyErr_SetString(PyExc_ValueError, "too many groups");
4801 return NULL;
4802 }
4803 for(i = 0; i < len; i++) {
4804 PyObject *elem;
4805 elem = PySequence_GetItem(groups, i);
4806 if (!elem)
4807 return NULL;
4808 if (!PyInt_Check(elem)) {
4809 PyErr_SetString(PyExc_TypeError,
4810 "groups must be integers");
4811 Py_DECREF(elem);
4812 return NULL;
4813 }
4814 /* XXX: check that value fits into gid_t. */
4815 grouplist[i] = PyInt_AsLong(elem);
4816 Py_DECREF(elem);
4817 }
4818
4819 if (setgroups(len, grouplist) < 0)
4820 return posix_error();
4821 Py_INCREF(Py_None);
4822 return Py_None;
4823}
4824#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004825
Guido van Rossumb6775db1994-08-01 11:34:53 +00004826#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004828"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Barry Warsaw53699e91996-12-10 23:23:01 +00004831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004832posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004833{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004834 int pid, options;
4835#ifdef UNION_WAIT
4836 union wait status;
4837#define status_i (status.w_status)
4838#else
4839 int status;
4840#define status_i status
4841#endif
4842 status_i = 0;
4843
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004844 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004845 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004847 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004848 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004849 if (pid == -1)
4850 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004851 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004852 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004853}
4854
Tim Petersab034fa2002-02-01 11:27:43 +00004855#elif defined(HAVE_CWAIT)
4856
4857/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004858PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004859"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004860"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004861
4862static PyObject *
4863posix_waitpid(PyObject *self, PyObject *args)
4864{
4865 int pid, options;
4866 int status;
4867
4868 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4869 return NULL;
4870 Py_BEGIN_ALLOW_THREADS
4871 pid = _cwait(&status, pid, options);
4872 Py_END_ALLOW_THREADS
4873 if (pid == -1)
4874 return posix_error();
4875 else
4876 /* shift the status left a byte so this is more like the
4877 POSIX waitpid */
4878 return Py_BuildValue("ii", pid, status << 8);
4879}
4880#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004881
Guido van Rossumad0ee831995-03-01 10:34:45 +00004882#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004883PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004884"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004886
Barry Warsaw53699e91996-12-10 23:23:01 +00004887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004888posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004889{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004890 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004891#ifdef UNION_WAIT
4892 union wait status;
4893#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004894#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004895 int status;
4896#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004897#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004898
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004899 status_i = 0;
4900 Py_BEGIN_ALLOW_THREADS
4901 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004902 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004903 if (pid == -1)
4904 return posix_error();
4905 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004906 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004907#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004908}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004909#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004912PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004913"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004915
Barry Warsaw53699e91996-12-10 23:23:01 +00004916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004917posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004918{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004919#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004920 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004921#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004922#ifdef MS_WINDOWS
4923 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4924#else
4925 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4926#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004927#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004928}
4929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004930
Guido van Rossumb6775db1994-08-01 11:34:53 +00004931#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Barry Warsaw53699e91996-12-10 23:23:01 +00004936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004937posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004938{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004939 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004940 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004941 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004942 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004943 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004944 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004945 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004946 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004947 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004948 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004949 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004950}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004951#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004953
Guido van Rossumb6775db1994-08-01 11:34:53 +00004954#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004955PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004956"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004957Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004958
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004960posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004961{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004962 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004963}
4964#endif /* HAVE_SYMLINK */
4965
4966
4967#ifdef HAVE_TIMES
4968#ifndef HZ
4969#define HZ 60 /* Universal constant :-) */
4970#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004971
Guido van Rossumd48f2521997-12-05 22:19:34 +00004972#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4973static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004974system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004975{
4976 ULONG value = 0;
4977
4978 Py_BEGIN_ALLOW_THREADS
4979 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4980 Py_END_ALLOW_THREADS
4981
4982 return value;
4983}
4984
4985static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004986posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004987{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004988 /* Currently Only Uptime is Provided -- Others Later */
4989 return Py_BuildValue("ddddd",
4990 (double)0 /* t.tms_utime / HZ */,
4991 (double)0 /* t.tms_stime / HZ */,
4992 (double)0 /* t.tms_cutime / HZ */,
4993 (double)0 /* t.tms_cstime / HZ */,
4994 (double)system_uptime() / 1000);
4995}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004996#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004998posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004999{
5000 struct tms t;
5001 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005002 errno = 0;
5003 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 if (c == (clock_t) -1)
5005 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005006 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005007 (double)t.tms_utime / HZ,
5008 (double)t.tms_stime / HZ,
5009 (double)t.tms_cutime / HZ,
5010 (double)t.tms_cstime / HZ,
5011 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005012}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005013#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005014#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005015
5016
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005017#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005018#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005019static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005020posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005021{
5022 FILETIME create, exit, kernel, user;
5023 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005024 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005025 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5026 /* The fields of a FILETIME structure are the hi and lo part
5027 of a 64-bit value expressed in 100 nanosecond units.
5028 1e7 is one second in such units; 1e-7 the inverse.
5029 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5030 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005031 return Py_BuildValue(
5032 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005033 (double)(kernel.dwHighDateTime*429.4967296 +
5034 kernel.dwLowDateTime*1e-7),
5035 (double)(user.dwHighDateTime*429.4967296 +
5036 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005037 (double)0,
5038 (double)0,
5039 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005040}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005041#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005042
5043#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005045"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005047#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005049
Guido van Rossumb6775db1994-08-01 11:34:53 +00005050#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005051PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005052"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Barry Warsaw53699e91996-12-10 23:23:01 +00005055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005056posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005057{
Guido van Rossum687dd131993-05-17 08:34:16 +00005058 if (setsid() < 0)
5059 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005060 Py_INCREF(Py_None);
5061 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005062}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005063#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005064
Guido van Rossumb6775db1994-08-01 11:34:53 +00005065#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005066PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005067"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Barry Warsaw53699e91996-12-10 23:23:01 +00005070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005071posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005072{
5073 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005074 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005075 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005076 if (setpgid(pid, pgrp) < 0)
5077 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005078 Py_INCREF(Py_None);
5079 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005080}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005081#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Guido van Rossumb6775db1994-08-01 11:34:53 +00005084#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005086"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005088
Barry Warsaw53699e91996-12-10 23:23:01 +00005089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005090posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005091{
5092 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005093 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005094 return NULL;
5095 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005096 if (pgid < 0)
5097 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005098 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005099}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005100#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005102
Guido van Rossumb6775db1994-08-01 11:34:53 +00005103#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005104PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005105"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005107
Barry Warsaw53699e91996-12-10 23:23:01 +00005108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005109posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005110{
5111 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005112 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005113 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005114 if (tcsetpgrp(fd, pgid) < 0)
5115 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005116 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005117 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005118}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005119#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005120
Guido van Rossum687dd131993-05-17 08:34:16 +00005121/* Functions acting on file descriptors */
5122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005124"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005126
Barry Warsaw53699e91996-12-10 23:23:01 +00005127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005128posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005129{
Mark Hammondef8b6542001-05-13 08:04:26 +00005130 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005131 int flag;
5132 int mode = 0777;
5133 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005134
5135#ifdef MS_WINDOWS
5136 if (unicode_file_names()) {
5137 PyUnicodeObject *po;
5138 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5139 Py_BEGIN_ALLOW_THREADS
5140 /* PyUnicode_AS_UNICODE OK without thread
5141 lock as it is a simple dereference. */
5142 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5143 Py_END_ALLOW_THREADS
5144 if (fd < 0)
5145 return posix_error();
5146 return PyInt_FromLong((long)fd);
5147 }
5148 /* Drop the argument parsing error as narrow strings
5149 are also valid. */
5150 PyErr_Clear();
5151 }
5152#endif
5153
Tim Peters5aa91602002-01-30 05:46:57 +00005154 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005155 Py_FileSystemDefaultEncoding, &file,
5156 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005157 return NULL;
5158
Barry Warsaw53699e91996-12-10 23:23:01 +00005159 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005160 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005161 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005162 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005163 return posix_error_with_allocated_filename(file);
5164 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005165 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005166}
5167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005169PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005170"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005171Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005172
Barry Warsaw53699e91996-12-10 23:23:01 +00005173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005174posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005175{
5176 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005177 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005178 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005179 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005180 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005181 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005182 if (res < 0)
5183 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005184 Py_INCREF(Py_None);
5185 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005186}
5187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005189PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005190"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005192
Barry Warsaw53699e91996-12-10 23:23:01 +00005193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005194posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005195{
5196 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005197 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005198 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005199 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005200 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005201 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005202 if (fd < 0)
5203 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005204 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005205}
5206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005209"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005211
Barry Warsaw53699e91996-12-10 23:23:01 +00005212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005213posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005214{
5215 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005216 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005217 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005218 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005219 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005220 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005221 if (res < 0)
5222 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005223 Py_INCREF(Py_None);
5224 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005225}
5226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005227
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005228PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005229"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Barry Warsaw53699e91996-12-10 23:23:01 +00005232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005233posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005234{
5235 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005236#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005237 LONG_LONG pos, res;
5238#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005239 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005240#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005241 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005242 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005243 return NULL;
5244#ifdef SEEK_SET
5245 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5246 switch (how) {
5247 case 0: how = SEEK_SET; break;
5248 case 1: how = SEEK_CUR; break;
5249 case 2: how = SEEK_END; break;
5250 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005251#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005252
5253#if !defined(HAVE_LARGEFILE_SUPPORT)
5254 pos = PyInt_AsLong(posobj);
5255#else
5256 pos = PyLong_Check(posobj) ?
5257 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5258#endif
5259 if (PyErr_Occurred())
5260 return NULL;
5261
Barry Warsaw53699e91996-12-10 23:23:01 +00005262 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005263#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005264 res = _lseeki64(fd, pos, how);
5265#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005266 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005267#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005268 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005269 if (res < 0)
5270 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005271
5272#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005273 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005274#else
5275 return PyLong_FromLongLong(res);
5276#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005277}
5278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005280PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005281"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005283
Barry Warsaw53699e91996-12-10 23:23:01 +00005284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005285posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005286{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005287 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005288 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005289 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005290 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005291 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005292 if (buffer == NULL)
5293 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005294 Py_BEGIN_ALLOW_THREADS
5295 n = read(fd, PyString_AsString(buffer), size);
5296 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005297 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005298 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005299 return posix_error();
5300 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005301 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005302 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005303 return buffer;
5304}
5305
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005306
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005308"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005310
Barry Warsaw53699e91996-12-10 23:23:01 +00005311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005312posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005313{
5314 int fd, size;
5315 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005316 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005317 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005318 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005319 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005320 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005321 if (size < 0)
5322 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005323 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005324}
5325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005327PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005328"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005330
Barry Warsaw53699e91996-12-10 23:23:01 +00005331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005332posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005333{
5334 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005335 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005336 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005337 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005339 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005340 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005341 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005342 if (res != 0)
5343 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005344
Fred Drake699f3522000-06-29 21:12:41 +00005345 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005346}
5347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005350"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005352
Barry Warsaw53699e91996-12-10 23:23:01 +00005353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005354posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005355{
Guido van Rossum687dd131993-05-17 08:34:16 +00005356 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005357 char *mode = "r";
5358 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005359 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005360 PyObject *f;
5361 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005362 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005363
Thomas Heller1f043e22002-11-07 16:00:59 +00005364 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5365 PyErr_Format(PyExc_ValueError,
5366 "invalid file mode '%s'", mode);
5367 return NULL;
5368 }
5369
Barry Warsaw53699e91996-12-10 23:23:01 +00005370 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005373 if (fp == NULL)
5374 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005375 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005376 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005377 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005378 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005379}
5380
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005382"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005383Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005385
5386static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005387posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005388{
5389 int fd;
5390 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5391 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005392 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005393}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005394
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005395#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005397"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005399
Barry Warsaw53699e91996-12-10 23:23:01 +00005400static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005401posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005402{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005403#if defined(PYOS_OS2)
5404 HFILE read, write;
5405 APIRET rc;
5406
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005407 Py_BEGIN_ALLOW_THREADS
5408 rc = DosCreatePipe( &read, &write, 4096);
5409 Py_END_ALLOW_THREADS
5410 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005411 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005412
5413 return Py_BuildValue("(ii)", read, write);
5414#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005415#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005416 int fds[2];
5417 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005418 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005419#if defined(__VMS)
5420 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5421#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005422 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005423#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005424 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005425 if (res != 0)
5426 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005427 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005428#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005429 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005430 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005431 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005432 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005433 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005434 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005435 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005436 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005437 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5438 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005439 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005440#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005441#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005442}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005443#endif /* HAVE_PIPE */
5444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005445
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005446#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005448"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005449Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005450
Barry Warsaw53699e91996-12-10 23:23:01 +00005451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005452posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005453{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005454 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005455 int mode = 0666;
5456 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005457 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005458 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005459 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005460 res = mkfifo(filename, mode);
5461 Py_END_ALLOW_THREADS
5462 if (res < 0)
5463 return posix_error();
5464 Py_INCREF(Py_None);
5465 return Py_None;
5466}
5467#endif
5468
5469
Neal Norwitz11690112002-07-30 01:08:28 +00005470#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005472"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005473Create a filesystem node (file, device special file or named pipe)\n\
5474named filename. mode specifies both the permissions to use and the\n\
5475type of node to be created, being combined (bitwise OR) with one of\n\
5476S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005477device defines the newly created device special file (probably using\n\
5478os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005479
5480
5481static PyObject *
5482posix_mknod(PyObject *self, PyObject *args)
5483{
5484 char *filename;
5485 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005486 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005487 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005488 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005489 return NULL;
5490 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005491 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005493 if (res < 0)
5494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 Py_INCREF(Py_None);
5496 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005497}
5498#endif
5499
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005500#ifdef HAVE_DEVICE_MACROS
5501PyDoc_STRVAR(posix_major__doc__,
5502"major(device) -> major number\n\
5503Extracts a device major number from a raw device number.");
5504
5505static PyObject *
5506posix_major(PyObject *self, PyObject *args)
5507{
5508 int device;
5509 if (!PyArg_ParseTuple(args, "i:major", &device))
5510 return NULL;
5511 return PyInt_FromLong((long)major(device));
5512}
5513
5514PyDoc_STRVAR(posix_minor__doc__,
5515"minor(device) -> minor number\n\
5516Extracts a device minor number from a raw device number.");
5517
5518static PyObject *
5519posix_minor(PyObject *self, PyObject *args)
5520{
5521 int device;
5522 if (!PyArg_ParseTuple(args, "i:minor", &device))
5523 return NULL;
5524 return PyInt_FromLong((long)minor(device));
5525}
5526
5527PyDoc_STRVAR(posix_makedev__doc__,
5528"makedev(major, minor) -> device number\n\
5529Composes a raw device number from the major and minor device numbers.");
5530
5531static PyObject *
5532posix_makedev(PyObject *self, PyObject *args)
5533{
5534 int major, minor;
5535 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5536 return NULL;
5537 return PyInt_FromLong((long)makedev(major, minor));
5538}
5539#endif /* device macros */
5540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005541
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005542#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005543PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005544"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005545Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546
Barry Warsaw53699e91996-12-10 23:23:01 +00005547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005548posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005549{
5550 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005551 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005552 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005553 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005554
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005555 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005556 return NULL;
5557
5558#if !defined(HAVE_LARGEFILE_SUPPORT)
5559 length = PyInt_AsLong(lenobj);
5560#else
5561 length = PyLong_Check(lenobj) ?
5562 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5563#endif
5564 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005565 return NULL;
5566
Barry Warsaw53699e91996-12-10 23:23:01 +00005567 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005568 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005569 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005570 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005571 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005572 return NULL;
5573 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005574 Py_INCREF(Py_None);
5575 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005576}
5577#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005578
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005579#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005580PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005581"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005583
Fred Drake762e2061999-08-26 17:23:54 +00005584/* Save putenv() parameters as values here, so we can collect them when they
5585 * get re-set with another call for the same key. */
5586static PyObject *posix_putenv_garbage;
5587
Tim Peters5aa91602002-01-30 05:46:57 +00005588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005589posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005590{
5591 char *s1, *s2;
5592 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005593 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005594 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005595
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005597 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005598
5599#if defined(PYOS_OS2)
5600 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5601 APIRET rc;
5602
5603 if (strlen(s2) == 0) /* If New Value is an Empty String */
5604 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5605
5606 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5607 if (rc != NO_ERROR)
5608 return os2_error(rc);
5609
5610 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5611 APIRET rc;
5612
5613 if (strlen(s2) == 0) /* If New Value is an Empty String */
5614 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5615
5616 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5617 if (rc != NO_ERROR)
5618 return os2_error(rc);
5619 } else {
5620#endif
5621
Fred Drake762e2061999-08-26 17:23:54 +00005622 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005623 len = strlen(s1) + strlen(s2) + 2;
5624 /* len includes space for a trailing \0; the size arg to
5625 PyString_FromStringAndSize does not count that */
5626 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005627 if (newstr == NULL)
5628 return PyErr_NoMemory();
5629 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005630 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005631 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005632 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005633 posix_error();
5634 return NULL;
5635 }
Fred Drake762e2061999-08-26 17:23:54 +00005636 /* Install the first arg and newstr in posix_putenv_garbage;
5637 * this will cause previous value to be collected. This has to
5638 * happen after the real putenv() call because the old value
5639 * was still accessible until then. */
5640 if (PyDict_SetItem(posix_putenv_garbage,
5641 PyTuple_GET_ITEM(args, 0), newstr)) {
5642 /* really not much we can do; just leak */
5643 PyErr_Clear();
5644 }
5645 else {
5646 Py_DECREF(newstr);
5647 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005648
5649#if defined(PYOS_OS2)
5650 }
5651#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005652 Py_INCREF(Py_None);
5653 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005654}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005655#endif /* putenv */
5656
Guido van Rossumc524d952001-10-19 01:31:59 +00005657#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005659"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005661
5662static PyObject *
5663posix_unsetenv(PyObject *self, PyObject *args)
5664{
5665 char *s1;
5666
5667 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5668 return NULL;
5669
5670 unsetenv(s1);
5671
5672 /* Remove the key from posix_putenv_garbage;
5673 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005674 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005675 * old value was still accessible until then.
5676 */
5677 if (PyDict_DelItem(posix_putenv_garbage,
5678 PyTuple_GET_ITEM(args, 0))) {
5679 /* really not much we can do; just leak */
5680 PyErr_Clear();
5681 }
5682
5683 Py_INCREF(Py_None);
5684 return Py_None;
5685}
5686#endif /* unsetenv */
5687
Guido van Rossumb6a47161997-09-15 22:54:34 +00005688#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005690"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005692
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005694posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005695{
5696 int code;
5697 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005698 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005699 return NULL;
5700 message = strerror(code);
5701 if (message == NULL) {
5702 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005703 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005704 return NULL;
5705 }
5706 return PyString_FromString(message);
5707}
5708#endif /* strerror */
5709
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005710
Guido van Rossumc9641791998-08-04 15:26:23 +00005711#ifdef HAVE_SYS_WAIT_H
5712
Fred Drake106c1a02002-04-23 15:58:02 +00005713#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005714PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005715"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005717
5718static PyObject *
5719posix_WCOREDUMP(PyObject *self, PyObject *args)
5720{
5721#ifdef UNION_WAIT
5722 union wait status;
5723#define status_i (status.w_status)
5724#else
5725 int status;
5726#define status_i status
5727#endif
5728 status_i = 0;
5729
5730 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5731 {
5732 return NULL;
5733 }
5734
5735 return PyBool_FromLong(WCOREDUMP(status));
5736#undef status_i
5737}
5738#endif /* WCOREDUMP */
5739
5740#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005741PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005742"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005743Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005745
5746static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005747posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005748{
5749#ifdef UNION_WAIT
5750 union wait status;
5751#define status_i (status.w_status)
5752#else
5753 int status;
5754#define status_i status
5755#endif
5756 status_i = 0;
5757
5758 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5759 {
5760 return NULL;
5761 }
5762
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005763 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005764#undef status_i
5765}
5766#endif /* WIFCONTINUED */
5767
Guido van Rossumc9641791998-08-04 15:26:23 +00005768#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005769PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005770"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005772
5773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005774posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005775{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005776#ifdef UNION_WAIT
5777 union wait status;
5778#define status_i (status.w_status)
5779#else
5780 int status;
5781#define status_i status
5782#endif
5783 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005784
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005785 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005786 {
5787 return NULL;
5788 }
Tim Peters5aa91602002-01-30 05:46:57 +00005789
Fred Drake106c1a02002-04-23 15:58:02 +00005790 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005792}
5793#endif /* WIFSTOPPED */
5794
5795#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005796PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005797"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005799
5800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005801posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005802{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005803#ifdef UNION_WAIT
5804 union wait status;
5805#define status_i (status.w_status)
5806#else
5807 int status;
5808#define status_i status
5809#endif
5810 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005811
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005812 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005813 {
5814 return NULL;
5815 }
Tim Peters5aa91602002-01-30 05:46:57 +00005816
Fred Drake106c1a02002-04-23 15:58:02 +00005817 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005818#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005819}
5820#endif /* WIFSIGNALED */
5821
5822#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005823PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005824"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005825Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005826system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005827
5828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005829posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005830{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005831#ifdef UNION_WAIT
5832 union wait status;
5833#define status_i (status.w_status)
5834#else
5835 int status;
5836#define status_i status
5837#endif
5838 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005839
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005840 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005841 {
5842 return NULL;
5843 }
Tim Peters5aa91602002-01-30 05:46:57 +00005844
Fred Drake106c1a02002-04-23 15:58:02 +00005845 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005846#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005847}
5848#endif /* WIFEXITED */
5849
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005850#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005851PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005852"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005854
5855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005856posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005857{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005858#ifdef UNION_WAIT
5859 union wait status;
5860#define status_i (status.w_status)
5861#else
5862 int status;
5863#define status_i status
5864#endif
5865 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005866
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005867 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005868 {
5869 return NULL;
5870 }
Tim Peters5aa91602002-01-30 05:46:57 +00005871
Guido van Rossumc9641791998-08-04 15:26:23 +00005872 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005873#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005874}
5875#endif /* WEXITSTATUS */
5876
5877#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005879"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005880Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005882
5883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005884posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005885{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005886#ifdef UNION_WAIT
5887 union wait status;
5888#define status_i (status.w_status)
5889#else
5890 int status;
5891#define status_i status
5892#endif
5893 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005894
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005895 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005896 {
5897 return NULL;
5898 }
Tim Peters5aa91602002-01-30 05:46:57 +00005899
Guido van Rossumc9641791998-08-04 15:26:23 +00005900 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005901#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005902}
5903#endif /* WTERMSIG */
5904
5905#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908Return the signal that stopped the process that provided\n\
5909the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005910
5911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005912posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005913{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005914#ifdef UNION_WAIT
5915 union wait status;
5916#define status_i (status.w_status)
5917#else
5918 int status;
5919#define status_i status
5920#endif
5921 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005923 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005924 {
5925 return NULL;
5926 }
Tim Peters5aa91602002-01-30 05:46:57 +00005927
Guido van Rossumc9641791998-08-04 15:26:23 +00005928 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005929#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005930}
5931#endif /* WSTOPSIG */
5932
5933#endif /* HAVE_SYS_WAIT_H */
5934
5935
Guido van Rossum94f6f721999-01-06 18:42:14 +00005936#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005937#ifdef _SCO_DS
5938/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5939 needed definitions in sys/statvfs.h */
5940#define _SVID3
5941#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005942#include <sys/statvfs.h>
5943
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005944static PyObject*
5945_pystatvfs_fromstructstatvfs(struct statvfs st) {
5946 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5947 if (v == NULL)
5948 return NULL;
5949
5950#if !defined(HAVE_LARGEFILE_SUPPORT)
5951 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5952 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5953 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5954 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5955 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5956 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5957 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5958 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5959 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5960 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5961#else
5962 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5963 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005964 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005965 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005966 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005967 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5968 PyStructSequence_SET_ITEM(v, 4,
5969 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005970 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005971 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005972 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005973 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005974 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005975 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5976 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5977 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5978#endif
5979
5980 return v;
5981}
5982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005984"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005986
5987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005988posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005989{
5990 int fd, res;
5991 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005992
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005993 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005994 return NULL;
5995 Py_BEGIN_ALLOW_THREADS
5996 res = fstatvfs(fd, &st);
5997 Py_END_ALLOW_THREADS
5998 if (res != 0)
5999 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006000
6001 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006002}
6003#endif /* HAVE_FSTATVFS */
6004
6005
6006#if defined(HAVE_STATVFS)
6007#include <sys/statvfs.h>
6008
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006009PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006010"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006012
6013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006014posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006015{
6016 char *path;
6017 int res;
6018 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006019 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006020 return NULL;
6021 Py_BEGIN_ALLOW_THREADS
6022 res = statvfs(path, &st);
6023 Py_END_ALLOW_THREADS
6024 if (res != 0)
6025 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006026
6027 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006028}
6029#endif /* HAVE_STATVFS */
6030
6031
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006032#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006034"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006035Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006036The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006037or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006038
6039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006040posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006041{
6042 PyObject *result = NULL;
6043 char *dir = NULL;
6044 char *pfx = NULL;
6045 char *name;
6046
6047 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6048 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006049
6050 if (PyErr_Warn(PyExc_RuntimeWarning,
6051 "tempnam is a potential security risk to your program") < 0)
6052 return NULL;
6053
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006054#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006055 name = _tempnam(dir, pfx);
6056#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006057 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006058#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006059 if (name == NULL)
6060 return PyErr_NoMemory();
6061 result = PyString_FromString(name);
6062 free(name);
6063 return result;
6064}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006065#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006066
6067
6068#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006069PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006070"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006072
6073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006074posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006075{
6076 FILE *fp;
6077
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006078 fp = tmpfile();
6079 if (fp == NULL)
6080 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006081 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006082}
6083#endif
6084
6085
6086#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006088"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006090
6091static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006092posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006093{
6094 char buffer[L_tmpnam];
6095 char *name;
6096
Skip Montanaro95618b52001-08-18 18:52:10 +00006097 if (PyErr_Warn(PyExc_RuntimeWarning,
6098 "tmpnam is a potential security risk to your program") < 0)
6099 return NULL;
6100
Greg Wardb48bc172000-03-01 21:51:56 +00006101#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006102 name = tmpnam_r(buffer);
6103#else
6104 name = tmpnam(buffer);
6105#endif
6106 if (name == NULL) {
6107 PyErr_SetObject(PyExc_OSError,
6108 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006109#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006110 "unexpected NULL from tmpnam_r"
6111#else
6112 "unexpected NULL from tmpnam"
6113#endif
6114 ));
6115 return NULL;
6116 }
6117 return PyString_FromString(buffer);
6118}
6119#endif
6120
6121
Fred Drakec9680921999-12-13 16:37:25 +00006122/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6123 * It maps strings representing configuration variable names to
6124 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006125 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006126 * rarely-used constants. There are three separate tables that use
6127 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006128 *
6129 * This code is always included, even if none of the interfaces that
6130 * need it are included. The #if hackery needed to avoid it would be
6131 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006132 */
6133struct constdef {
6134 char *name;
6135 long value;
6136};
6137
Fred Drake12c6e2d1999-12-14 21:25:03 +00006138static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006139conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6140 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006141{
6142 if (PyInt_Check(arg)) {
6143 *valuep = PyInt_AS_LONG(arg);
6144 return 1;
6145 }
6146 if (PyString_Check(arg)) {
6147 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006148 size_t lo = 0;
6149 size_t mid;
6150 size_t hi = tablesize;
6151 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006152 char *confname = PyString_AS_STRING(arg);
6153 while (lo < hi) {
6154 mid = (lo + hi) / 2;
6155 cmp = strcmp(confname, table[mid].name);
6156 if (cmp < 0)
6157 hi = mid;
6158 else if (cmp > 0)
6159 lo = mid + 1;
6160 else {
6161 *valuep = table[mid].value;
6162 return 1;
6163 }
6164 }
6165 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6166 }
6167 else
6168 PyErr_SetString(PyExc_TypeError,
6169 "configuration names must be strings or integers");
6170 return 0;
6171}
6172
6173
6174#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6175static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006176#ifdef _PC_ABI_AIO_XFER_MAX
6177 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6178#endif
6179#ifdef _PC_ABI_ASYNC_IO
6180 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6181#endif
Fred Drakec9680921999-12-13 16:37:25 +00006182#ifdef _PC_ASYNC_IO
6183 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6184#endif
6185#ifdef _PC_CHOWN_RESTRICTED
6186 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6187#endif
6188#ifdef _PC_FILESIZEBITS
6189 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6190#endif
6191#ifdef _PC_LAST
6192 {"PC_LAST", _PC_LAST},
6193#endif
6194#ifdef _PC_LINK_MAX
6195 {"PC_LINK_MAX", _PC_LINK_MAX},
6196#endif
6197#ifdef _PC_MAX_CANON
6198 {"PC_MAX_CANON", _PC_MAX_CANON},
6199#endif
6200#ifdef _PC_MAX_INPUT
6201 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6202#endif
6203#ifdef _PC_NAME_MAX
6204 {"PC_NAME_MAX", _PC_NAME_MAX},
6205#endif
6206#ifdef _PC_NO_TRUNC
6207 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6208#endif
6209#ifdef _PC_PATH_MAX
6210 {"PC_PATH_MAX", _PC_PATH_MAX},
6211#endif
6212#ifdef _PC_PIPE_BUF
6213 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6214#endif
6215#ifdef _PC_PRIO_IO
6216 {"PC_PRIO_IO", _PC_PRIO_IO},
6217#endif
6218#ifdef _PC_SOCK_MAXBUF
6219 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6220#endif
6221#ifdef _PC_SYNC_IO
6222 {"PC_SYNC_IO", _PC_SYNC_IO},
6223#endif
6224#ifdef _PC_VDISABLE
6225 {"PC_VDISABLE", _PC_VDISABLE},
6226#endif
6227};
6228
Fred Drakec9680921999-12-13 16:37:25 +00006229static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006230conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006231{
6232 return conv_confname(arg, valuep, posix_constants_pathconf,
6233 sizeof(posix_constants_pathconf)
6234 / sizeof(struct constdef));
6235}
6236#endif
6237
6238#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006240"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006241Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006242If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006243
6244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006245posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006246{
6247 PyObject *result = NULL;
6248 int name, fd;
6249
Fred Drake12c6e2d1999-12-14 21:25:03 +00006250 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6251 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006252 long limit;
6253
6254 errno = 0;
6255 limit = fpathconf(fd, name);
6256 if (limit == -1 && errno != 0)
6257 posix_error();
6258 else
6259 result = PyInt_FromLong(limit);
6260 }
6261 return result;
6262}
6263#endif
6264
6265
6266#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006268"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006269Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006271
6272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006273posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006274{
6275 PyObject *result = NULL;
6276 int name;
6277 char *path;
6278
6279 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6280 conv_path_confname, &name)) {
6281 long limit;
6282
6283 errno = 0;
6284 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006285 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006286 if (errno == EINVAL)
6287 /* could be a path or name problem */
6288 posix_error();
6289 else
6290 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006291 }
Fred Drakec9680921999-12-13 16:37:25 +00006292 else
6293 result = PyInt_FromLong(limit);
6294 }
6295 return result;
6296}
6297#endif
6298
6299#ifdef HAVE_CONFSTR
6300static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006301#ifdef _CS_ARCHITECTURE
6302 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6303#endif
6304#ifdef _CS_HOSTNAME
6305 {"CS_HOSTNAME", _CS_HOSTNAME},
6306#endif
6307#ifdef _CS_HW_PROVIDER
6308 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6309#endif
6310#ifdef _CS_HW_SERIAL
6311 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6312#endif
6313#ifdef _CS_INITTAB_NAME
6314 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6315#endif
Fred Drakec9680921999-12-13 16:37:25 +00006316#ifdef _CS_LFS64_CFLAGS
6317 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6318#endif
6319#ifdef _CS_LFS64_LDFLAGS
6320 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6321#endif
6322#ifdef _CS_LFS64_LIBS
6323 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6324#endif
6325#ifdef _CS_LFS64_LINTFLAGS
6326 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6327#endif
6328#ifdef _CS_LFS_CFLAGS
6329 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6330#endif
6331#ifdef _CS_LFS_LDFLAGS
6332 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6333#endif
6334#ifdef _CS_LFS_LIBS
6335 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6336#endif
6337#ifdef _CS_LFS_LINTFLAGS
6338 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6339#endif
Fred Draked86ed291999-12-15 15:34:33 +00006340#ifdef _CS_MACHINE
6341 {"CS_MACHINE", _CS_MACHINE},
6342#endif
Fred Drakec9680921999-12-13 16:37:25 +00006343#ifdef _CS_PATH
6344 {"CS_PATH", _CS_PATH},
6345#endif
Fred Draked86ed291999-12-15 15:34:33 +00006346#ifdef _CS_RELEASE
6347 {"CS_RELEASE", _CS_RELEASE},
6348#endif
6349#ifdef _CS_SRPC_DOMAIN
6350 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6351#endif
6352#ifdef _CS_SYSNAME
6353 {"CS_SYSNAME", _CS_SYSNAME},
6354#endif
6355#ifdef _CS_VERSION
6356 {"CS_VERSION", _CS_VERSION},
6357#endif
Fred Drakec9680921999-12-13 16:37:25 +00006358#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6359 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6360#endif
6361#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6362 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6363#endif
6364#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6365 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6366#endif
6367#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6368 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6369#endif
6370#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6371 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6372#endif
6373#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6374 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6375#endif
6376#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6377 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6378#endif
6379#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6380 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6381#endif
6382#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6383 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6384#endif
6385#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6386 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6387#endif
6388#ifdef _CS_XBS5_LP64_OFF64_LIBS
6389 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6390#endif
6391#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6392 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6393#endif
6394#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6395 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6396#endif
6397#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6398 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6399#endif
6400#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6401 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6402#endif
6403#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6404 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6405#endif
Fred Draked86ed291999-12-15 15:34:33 +00006406#ifdef _MIPS_CS_AVAIL_PROCESSORS
6407 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6408#endif
6409#ifdef _MIPS_CS_BASE
6410 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6411#endif
6412#ifdef _MIPS_CS_HOSTID
6413 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6414#endif
6415#ifdef _MIPS_CS_HW_NAME
6416 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6417#endif
6418#ifdef _MIPS_CS_NUM_PROCESSORS
6419 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6420#endif
6421#ifdef _MIPS_CS_OSREL_MAJ
6422 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6423#endif
6424#ifdef _MIPS_CS_OSREL_MIN
6425 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6426#endif
6427#ifdef _MIPS_CS_OSREL_PATCH
6428 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6429#endif
6430#ifdef _MIPS_CS_OS_NAME
6431 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6432#endif
6433#ifdef _MIPS_CS_OS_PROVIDER
6434 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6435#endif
6436#ifdef _MIPS_CS_PROCESSORS
6437 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6438#endif
6439#ifdef _MIPS_CS_SERIAL
6440 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6441#endif
6442#ifdef _MIPS_CS_VENDOR
6443 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6444#endif
Fred Drakec9680921999-12-13 16:37:25 +00006445};
6446
6447static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006448conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006449{
6450 return conv_confname(arg, valuep, posix_constants_confstr,
6451 sizeof(posix_constants_confstr)
6452 / sizeof(struct constdef));
6453}
6454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006456"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006458
6459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006460posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006461{
6462 PyObject *result = NULL;
6463 int name;
6464 char buffer[64];
6465
6466 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6467 int len = confstr(name, buffer, sizeof(buffer));
6468
Fred Drakec9680921999-12-13 16:37:25 +00006469 errno = 0;
6470 if (len == 0) {
6471 if (errno != 0)
6472 posix_error();
6473 else
6474 result = PyString_FromString("");
6475 }
6476 else {
6477 if (len >= sizeof(buffer)) {
6478 result = PyString_FromStringAndSize(NULL, len);
6479 if (result != NULL)
6480 confstr(name, PyString_AS_STRING(result), len+1);
6481 }
6482 else
6483 result = PyString_FromString(buffer);
6484 }
6485 }
6486 return result;
6487}
6488#endif
6489
6490
6491#ifdef HAVE_SYSCONF
6492static struct constdef posix_constants_sysconf[] = {
6493#ifdef _SC_2_CHAR_TERM
6494 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6495#endif
6496#ifdef _SC_2_C_BIND
6497 {"SC_2_C_BIND", _SC_2_C_BIND},
6498#endif
6499#ifdef _SC_2_C_DEV
6500 {"SC_2_C_DEV", _SC_2_C_DEV},
6501#endif
6502#ifdef _SC_2_C_VERSION
6503 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6504#endif
6505#ifdef _SC_2_FORT_DEV
6506 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6507#endif
6508#ifdef _SC_2_FORT_RUN
6509 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6510#endif
6511#ifdef _SC_2_LOCALEDEF
6512 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6513#endif
6514#ifdef _SC_2_SW_DEV
6515 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6516#endif
6517#ifdef _SC_2_UPE
6518 {"SC_2_UPE", _SC_2_UPE},
6519#endif
6520#ifdef _SC_2_VERSION
6521 {"SC_2_VERSION", _SC_2_VERSION},
6522#endif
Fred Draked86ed291999-12-15 15:34:33 +00006523#ifdef _SC_ABI_ASYNCHRONOUS_IO
6524 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6525#endif
6526#ifdef _SC_ACL
6527 {"SC_ACL", _SC_ACL},
6528#endif
Fred Drakec9680921999-12-13 16:37:25 +00006529#ifdef _SC_AIO_LISTIO_MAX
6530 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6531#endif
Fred Drakec9680921999-12-13 16:37:25 +00006532#ifdef _SC_AIO_MAX
6533 {"SC_AIO_MAX", _SC_AIO_MAX},
6534#endif
6535#ifdef _SC_AIO_PRIO_DELTA_MAX
6536 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6537#endif
6538#ifdef _SC_ARG_MAX
6539 {"SC_ARG_MAX", _SC_ARG_MAX},
6540#endif
6541#ifdef _SC_ASYNCHRONOUS_IO
6542 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6543#endif
6544#ifdef _SC_ATEXIT_MAX
6545 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6546#endif
Fred Draked86ed291999-12-15 15:34:33 +00006547#ifdef _SC_AUDIT
6548 {"SC_AUDIT", _SC_AUDIT},
6549#endif
Fred Drakec9680921999-12-13 16:37:25 +00006550#ifdef _SC_AVPHYS_PAGES
6551 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6552#endif
6553#ifdef _SC_BC_BASE_MAX
6554 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6555#endif
6556#ifdef _SC_BC_DIM_MAX
6557 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6558#endif
6559#ifdef _SC_BC_SCALE_MAX
6560 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6561#endif
6562#ifdef _SC_BC_STRING_MAX
6563 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6564#endif
Fred Draked86ed291999-12-15 15:34:33 +00006565#ifdef _SC_CAP
6566 {"SC_CAP", _SC_CAP},
6567#endif
Fred Drakec9680921999-12-13 16:37:25 +00006568#ifdef _SC_CHARCLASS_NAME_MAX
6569 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6570#endif
6571#ifdef _SC_CHAR_BIT
6572 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6573#endif
6574#ifdef _SC_CHAR_MAX
6575 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6576#endif
6577#ifdef _SC_CHAR_MIN
6578 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6579#endif
6580#ifdef _SC_CHILD_MAX
6581 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6582#endif
6583#ifdef _SC_CLK_TCK
6584 {"SC_CLK_TCK", _SC_CLK_TCK},
6585#endif
6586#ifdef _SC_COHER_BLKSZ
6587 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6588#endif
6589#ifdef _SC_COLL_WEIGHTS_MAX
6590 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6591#endif
6592#ifdef _SC_DCACHE_ASSOC
6593 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6594#endif
6595#ifdef _SC_DCACHE_BLKSZ
6596 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6597#endif
6598#ifdef _SC_DCACHE_LINESZ
6599 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6600#endif
6601#ifdef _SC_DCACHE_SZ
6602 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6603#endif
6604#ifdef _SC_DCACHE_TBLKSZ
6605 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6606#endif
6607#ifdef _SC_DELAYTIMER_MAX
6608 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6609#endif
6610#ifdef _SC_EQUIV_CLASS_MAX
6611 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6612#endif
6613#ifdef _SC_EXPR_NEST_MAX
6614 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6615#endif
6616#ifdef _SC_FSYNC
6617 {"SC_FSYNC", _SC_FSYNC},
6618#endif
6619#ifdef _SC_GETGR_R_SIZE_MAX
6620 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6621#endif
6622#ifdef _SC_GETPW_R_SIZE_MAX
6623 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6624#endif
6625#ifdef _SC_ICACHE_ASSOC
6626 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6627#endif
6628#ifdef _SC_ICACHE_BLKSZ
6629 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6630#endif
6631#ifdef _SC_ICACHE_LINESZ
6632 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6633#endif
6634#ifdef _SC_ICACHE_SZ
6635 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6636#endif
Fred Draked86ed291999-12-15 15:34:33 +00006637#ifdef _SC_INF
6638 {"SC_INF", _SC_INF},
6639#endif
Fred Drakec9680921999-12-13 16:37:25 +00006640#ifdef _SC_INT_MAX
6641 {"SC_INT_MAX", _SC_INT_MAX},
6642#endif
6643#ifdef _SC_INT_MIN
6644 {"SC_INT_MIN", _SC_INT_MIN},
6645#endif
6646#ifdef _SC_IOV_MAX
6647 {"SC_IOV_MAX", _SC_IOV_MAX},
6648#endif
Fred Draked86ed291999-12-15 15:34:33 +00006649#ifdef _SC_IP_SECOPTS
6650 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6651#endif
Fred Drakec9680921999-12-13 16:37:25 +00006652#ifdef _SC_JOB_CONTROL
6653 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6654#endif
Fred Draked86ed291999-12-15 15:34:33 +00006655#ifdef _SC_KERN_POINTERS
6656 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6657#endif
6658#ifdef _SC_KERN_SIM
6659 {"SC_KERN_SIM", _SC_KERN_SIM},
6660#endif
Fred Drakec9680921999-12-13 16:37:25 +00006661#ifdef _SC_LINE_MAX
6662 {"SC_LINE_MAX", _SC_LINE_MAX},
6663#endif
6664#ifdef _SC_LOGIN_NAME_MAX
6665 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6666#endif
6667#ifdef _SC_LOGNAME_MAX
6668 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6669#endif
6670#ifdef _SC_LONG_BIT
6671 {"SC_LONG_BIT", _SC_LONG_BIT},
6672#endif
Fred Draked86ed291999-12-15 15:34:33 +00006673#ifdef _SC_MAC
6674 {"SC_MAC", _SC_MAC},
6675#endif
Fred Drakec9680921999-12-13 16:37:25 +00006676#ifdef _SC_MAPPED_FILES
6677 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6678#endif
6679#ifdef _SC_MAXPID
6680 {"SC_MAXPID", _SC_MAXPID},
6681#endif
6682#ifdef _SC_MB_LEN_MAX
6683 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6684#endif
6685#ifdef _SC_MEMLOCK
6686 {"SC_MEMLOCK", _SC_MEMLOCK},
6687#endif
6688#ifdef _SC_MEMLOCK_RANGE
6689 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6690#endif
6691#ifdef _SC_MEMORY_PROTECTION
6692 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6693#endif
6694#ifdef _SC_MESSAGE_PASSING
6695 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6696#endif
Fred Draked86ed291999-12-15 15:34:33 +00006697#ifdef _SC_MMAP_FIXED_ALIGNMENT
6698 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6699#endif
Fred Drakec9680921999-12-13 16:37:25 +00006700#ifdef _SC_MQ_OPEN_MAX
6701 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6702#endif
6703#ifdef _SC_MQ_PRIO_MAX
6704 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6705#endif
Fred Draked86ed291999-12-15 15:34:33 +00006706#ifdef _SC_NACLS_MAX
6707 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6708#endif
Fred Drakec9680921999-12-13 16:37:25 +00006709#ifdef _SC_NGROUPS_MAX
6710 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6711#endif
6712#ifdef _SC_NL_ARGMAX
6713 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6714#endif
6715#ifdef _SC_NL_LANGMAX
6716 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6717#endif
6718#ifdef _SC_NL_MSGMAX
6719 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6720#endif
6721#ifdef _SC_NL_NMAX
6722 {"SC_NL_NMAX", _SC_NL_NMAX},
6723#endif
6724#ifdef _SC_NL_SETMAX
6725 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6726#endif
6727#ifdef _SC_NL_TEXTMAX
6728 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6729#endif
6730#ifdef _SC_NPROCESSORS_CONF
6731 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6732#endif
6733#ifdef _SC_NPROCESSORS_ONLN
6734 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6735#endif
Fred Draked86ed291999-12-15 15:34:33 +00006736#ifdef _SC_NPROC_CONF
6737 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6738#endif
6739#ifdef _SC_NPROC_ONLN
6740 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6741#endif
Fred Drakec9680921999-12-13 16:37:25 +00006742#ifdef _SC_NZERO
6743 {"SC_NZERO", _SC_NZERO},
6744#endif
6745#ifdef _SC_OPEN_MAX
6746 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6747#endif
6748#ifdef _SC_PAGESIZE
6749 {"SC_PAGESIZE", _SC_PAGESIZE},
6750#endif
6751#ifdef _SC_PAGE_SIZE
6752 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6753#endif
6754#ifdef _SC_PASS_MAX
6755 {"SC_PASS_MAX", _SC_PASS_MAX},
6756#endif
6757#ifdef _SC_PHYS_PAGES
6758 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6759#endif
6760#ifdef _SC_PII
6761 {"SC_PII", _SC_PII},
6762#endif
6763#ifdef _SC_PII_INTERNET
6764 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6765#endif
6766#ifdef _SC_PII_INTERNET_DGRAM
6767 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6768#endif
6769#ifdef _SC_PII_INTERNET_STREAM
6770 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6771#endif
6772#ifdef _SC_PII_OSI
6773 {"SC_PII_OSI", _SC_PII_OSI},
6774#endif
6775#ifdef _SC_PII_OSI_CLTS
6776 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6777#endif
6778#ifdef _SC_PII_OSI_COTS
6779 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6780#endif
6781#ifdef _SC_PII_OSI_M
6782 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6783#endif
6784#ifdef _SC_PII_SOCKET
6785 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6786#endif
6787#ifdef _SC_PII_XTI
6788 {"SC_PII_XTI", _SC_PII_XTI},
6789#endif
6790#ifdef _SC_POLL
6791 {"SC_POLL", _SC_POLL},
6792#endif
6793#ifdef _SC_PRIORITIZED_IO
6794 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6795#endif
6796#ifdef _SC_PRIORITY_SCHEDULING
6797 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6798#endif
6799#ifdef _SC_REALTIME_SIGNALS
6800 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6801#endif
6802#ifdef _SC_RE_DUP_MAX
6803 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6804#endif
6805#ifdef _SC_RTSIG_MAX
6806 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6807#endif
6808#ifdef _SC_SAVED_IDS
6809 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6810#endif
6811#ifdef _SC_SCHAR_MAX
6812 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6813#endif
6814#ifdef _SC_SCHAR_MIN
6815 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6816#endif
6817#ifdef _SC_SELECT
6818 {"SC_SELECT", _SC_SELECT},
6819#endif
6820#ifdef _SC_SEMAPHORES
6821 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6822#endif
6823#ifdef _SC_SEM_NSEMS_MAX
6824 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6825#endif
6826#ifdef _SC_SEM_VALUE_MAX
6827 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6828#endif
6829#ifdef _SC_SHARED_MEMORY_OBJECTS
6830 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6831#endif
6832#ifdef _SC_SHRT_MAX
6833 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6834#endif
6835#ifdef _SC_SHRT_MIN
6836 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6837#endif
6838#ifdef _SC_SIGQUEUE_MAX
6839 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6840#endif
6841#ifdef _SC_SIGRT_MAX
6842 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6843#endif
6844#ifdef _SC_SIGRT_MIN
6845 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6846#endif
Fred Draked86ed291999-12-15 15:34:33 +00006847#ifdef _SC_SOFTPOWER
6848 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6849#endif
Fred Drakec9680921999-12-13 16:37:25 +00006850#ifdef _SC_SPLIT_CACHE
6851 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6852#endif
6853#ifdef _SC_SSIZE_MAX
6854 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6855#endif
6856#ifdef _SC_STACK_PROT
6857 {"SC_STACK_PROT", _SC_STACK_PROT},
6858#endif
6859#ifdef _SC_STREAM_MAX
6860 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6861#endif
6862#ifdef _SC_SYNCHRONIZED_IO
6863 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6864#endif
6865#ifdef _SC_THREADS
6866 {"SC_THREADS", _SC_THREADS},
6867#endif
6868#ifdef _SC_THREAD_ATTR_STACKADDR
6869 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6870#endif
6871#ifdef _SC_THREAD_ATTR_STACKSIZE
6872 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6873#endif
6874#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6875 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6876#endif
6877#ifdef _SC_THREAD_KEYS_MAX
6878 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6879#endif
6880#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6881 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6882#endif
6883#ifdef _SC_THREAD_PRIO_INHERIT
6884 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6885#endif
6886#ifdef _SC_THREAD_PRIO_PROTECT
6887 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6888#endif
6889#ifdef _SC_THREAD_PROCESS_SHARED
6890 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6891#endif
6892#ifdef _SC_THREAD_SAFE_FUNCTIONS
6893 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6894#endif
6895#ifdef _SC_THREAD_STACK_MIN
6896 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6897#endif
6898#ifdef _SC_THREAD_THREADS_MAX
6899 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6900#endif
6901#ifdef _SC_TIMERS
6902 {"SC_TIMERS", _SC_TIMERS},
6903#endif
6904#ifdef _SC_TIMER_MAX
6905 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6906#endif
6907#ifdef _SC_TTY_NAME_MAX
6908 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6909#endif
6910#ifdef _SC_TZNAME_MAX
6911 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6912#endif
6913#ifdef _SC_T_IOV_MAX
6914 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6915#endif
6916#ifdef _SC_UCHAR_MAX
6917 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6918#endif
6919#ifdef _SC_UINT_MAX
6920 {"SC_UINT_MAX", _SC_UINT_MAX},
6921#endif
6922#ifdef _SC_UIO_MAXIOV
6923 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6924#endif
6925#ifdef _SC_ULONG_MAX
6926 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6927#endif
6928#ifdef _SC_USHRT_MAX
6929 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6930#endif
6931#ifdef _SC_VERSION
6932 {"SC_VERSION", _SC_VERSION},
6933#endif
6934#ifdef _SC_WORD_BIT
6935 {"SC_WORD_BIT", _SC_WORD_BIT},
6936#endif
6937#ifdef _SC_XBS5_ILP32_OFF32
6938 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6939#endif
6940#ifdef _SC_XBS5_ILP32_OFFBIG
6941 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6942#endif
6943#ifdef _SC_XBS5_LP64_OFF64
6944 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6945#endif
6946#ifdef _SC_XBS5_LPBIG_OFFBIG
6947 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6948#endif
6949#ifdef _SC_XOPEN_CRYPT
6950 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6951#endif
6952#ifdef _SC_XOPEN_ENH_I18N
6953 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6954#endif
6955#ifdef _SC_XOPEN_LEGACY
6956 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6957#endif
6958#ifdef _SC_XOPEN_REALTIME
6959 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6960#endif
6961#ifdef _SC_XOPEN_REALTIME_THREADS
6962 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6963#endif
6964#ifdef _SC_XOPEN_SHM
6965 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6966#endif
6967#ifdef _SC_XOPEN_UNIX
6968 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6969#endif
6970#ifdef _SC_XOPEN_VERSION
6971 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6972#endif
6973#ifdef _SC_XOPEN_XCU_VERSION
6974 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6975#endif
6976#ifdef _SC_XOPEN_XPG2
6977 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6978#endif
6979#ifdef _SC_XOPEN_XPG3
6980 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6981#endif
6982#ifdef _SC_XOPEN_XPG4
6983 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6984#endif
6985};
6986
6987static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006988conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006989{
6990 return conv_confname(arg, valuep, posix_constants_sysconf,
6991 sizeof(posix_constants_sysconf)
6992 / sizeof(struct constdef));
6993}
6994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006995PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006996"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006997Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006998
6999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007000posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007001{
7002 PyObject *result = NULL;
7003 int name;
7004
7005 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7006 int value;
7007
7008 errno = 0;
7009 value = sysconf(name);
7010 if (value == -1 && errno != 0)
7011 posix_error();
7012 else
7013 result = PyInt_FromLong(value);
7014 }
7015 return result;
7016}
7017#endif
7018
7019
Fred Drakebec628d1999-12-15 18:31:10 +00007020/* This code is used to ensure that the tables of configuration value names
7021 * are in sorted order as required by conv_confname(), and also to build the
7022 * the exported dictionaries that are used to publish information about the
7023 * names available on the host platform.
7024 *
7025 * Sorting the table at runtime ensures that the table is properly ordered
7026 * when used, even for platforms we're not able to test on. It also makes
7027 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007028 */
Fred Drakebec628d1999-12-15 18:31:10 +00007029
7030static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007031cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007032{
7033 const struct constdef *c1 =
7034 (const struct constdef *) v1;
7035 const struct constdef *c2 =
7036 (const struct constdef *) v2;
7037
7038 return strcmp(c1->name, c2->name);
7039}
7040
7041static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007042setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007043 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007044{
Fred Drakebec628d1999-12-15 18:31:10 +00007045 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007046 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007047
7048 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7049 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007050 if (d == NULL)
7051 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007052
Barry Warsaw3155db32000-04-13 15:20:40 +00007053 for (i=0; i < tablesize; ++i) {
7054 PyObject *o = PyInt_FromLong(table[i].value);
7055 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7056 Py_XDECREF(o);
7057 Py_DECREF(d);
7058 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007059 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007060 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007061 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007062 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007063}
7064
Fred Drakebec628d1999-12-15 18:31:10 +00007065/* Return -1 on failure, 0 on success. */
7066static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007067setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007068{
7069#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007070 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007071 sizeof(posix_constants_pathconf)
7072 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007073 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007074 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007075#endif
7076#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007077 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007078 sizeof(posix_constants_confstr)
7079 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007080 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007081 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007082#endif
7083#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007084 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007085 sizeof(posix_constants_sysconf)
7086 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007087 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007088 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007089#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007090 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007091}
Fred Draked86ed291999-12-15 15:34:33 +00007092
7093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007094PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007095"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007096Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007097in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098
7099static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007100posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007101{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007102 abort();
7103 /*NOTREACHED*/
7104 Py_FatalError("abort() called from Python code didn't abort!");
7105 return NULL;
7106}
Fred Drakebec628d1999-12-15 18:31:10 +00007107
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007108#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007109PyDoc_STRVAR(win32_startfile__doc__,
7110"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007111\n\
7112This acts like double-clicking the file in Explorer, or giving the file\n\
7113name as an argument to the DOS \"start\" command: the file is opened\n\
7114with whatever application (if any) its extension is associated.\n\
7115\n\
7116startfile returns as soon as the associated application is launched.\n\
7117There is no option to wait for the application to close, and no way\n\
7118to retrieve the application's exit status.\n\
7119\n\
7120The filepath is relative to the current directory. If you want to use\n\
7121an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007122the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007123
7124static PyObject *
7125win32_startfile(PyObject *self, PyObject *args)
7126{
7127 char *filepath;
7128 HINSTANCE rc;
7129 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7130 return NULL;
7131 Py_BEGIN_ALLOW_THREADS
7132 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7133 Py_END_ALLOW_THREADS
7134 if (rc <= (HINSTANCE)32)
7135 return win32_error("startfile", filepath);
7136 Py_INCREF(Py_None);
7137 return Py_None;
7138}
7139#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007140
Martin v. Löwis438b5342002-12-27 10:16:42 +00007141#ifdef HAVE_GETLOADAVG
7142PyDoc_STRVAR(posix_getloadavg__doc__,
7143"getloadavg() -> (float, float, float)\n\n\
7144Return the number of processes in the system run queue averaged over\n\
7145the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7146was unobtainable");
7147
7148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007149posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007150{
7151 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007152 if (getloadavg(loadavg, 3)!=3) {
7153 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7154 return NULL;
7155 } else
7156 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7157}
7158#endif
7159
7160
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007161static PyMethodDef posix_methods[] = {
7162 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7163#ifdef HAVE_TTYNAME
7164 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7165#endif
7166 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7167 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007168#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007170#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007171#ifdef HAVE_LCHOWN
7172 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7173#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007174#ifdef HAVE_CHROOT
7175 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7176#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007177#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007178 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007180#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007181 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007182#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007183 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007184#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007185#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007186#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007188#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007189 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7190 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7191 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007192#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007193 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007194#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007195#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007197#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7199 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7200 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007201 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007202#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007204#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007205#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007207#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007208 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007209#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007210 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007211#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7213 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7214 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007215#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007216 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007217#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007218 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007219#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007220 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7221 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007222#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007223#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7225 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007226#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007227#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007228 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007229#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007230#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007231 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007232#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007233#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007234 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007235#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007236#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007237 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007238#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007239#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007240 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007241#endif /* HAVE_GETEGID */
7242#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007243 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007244#endif /* HAVE_GETEUID */
7245#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007246 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007247#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007248#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007249 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007251 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007252#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007253 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007254#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007255#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007256 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007257#endif /* HAVE_GETPPID */
7258#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007259 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007260#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007261#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007262 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007263#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007264#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007265 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007266#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007267#ifdef HAVE_KILLPG
7268 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7269#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007270#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007271 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007272#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007273#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007274 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007275#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007276 {"popen2", win32_popen2, METH_VARARGS},
7277 {"popen3", win32_popen3, METH_VARARGS},
7278 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007279 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007280#else
7281#if defined(PYOS_OS2) && defined(PYCC_GCC)
7282 {"popen2", os2emx_popen2, METH_VARARGS},
7283 {"popen3", os2emx_popen3, METH_VARARGS},
7284 {"popen4", os2emx_popen4, METH_VARARGS},
7285#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007286#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007287#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007288#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007289 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007290#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007291#ifdef HAVE_SETEUID
7292 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7293#endif /* HAVE_SETEUID */
7294#ifdef HAVE_SETEGID
7295 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7296#endif /* HAVE_SETEGID */
7297#ifdef HAVE_SETREUID
7298 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7299#endif /* HAVE_SETREUID */
7300#ifdef HAVE_SETREGID
7301 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7302#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007303#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007304 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007305#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007306#ifdef HAVE_SETGROUPS
7307 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7308#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007309#ifdef HAVE_GETPGID
7310 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7311#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007312#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007313 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007314#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007315#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007316 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007317#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007318#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007319 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007320#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007321#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007322 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007323#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007324#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007325 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007326#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007327#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007328 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007329#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007330#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007332#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007333 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7334 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7335 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7336 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7337 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7338 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7339 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7340 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7341 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007342 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007343#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007344 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007345#endif
7346#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007347 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007348#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007349#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007350 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7351#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007352#ifdef HAVE_DEVICE_MACROS
7353 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7354 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7355 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7356#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007357#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007358 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007359#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007360#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007361 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007362#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007363#ifdef HAVE_UNSETENV
7364 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7365#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007366#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007368#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007369#ifdef HAVE_FCHDIR
7370 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7371#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007372#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007373 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007374#endif
7375#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007376 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007377#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007378#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007379#ifdef WCOREDUMP
7380 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7381#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007382#ifdef WIFCONTINUED
7383 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7384#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007385#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007387#endif /* WIFSTOPPED */
7388#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007390#endif /* WIFSIGNALED */
7391#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007393#endif /* WIFEXITED */
7394#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007395 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007396#endif /* WEXITSTATUS */
7397#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007398 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007399#endif /* WTERMSIG */
7400#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007401 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007402#endif /* WSTOPSIG */
7403#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007404#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007405 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007406#endif
7407#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007408 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007409#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007410#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007411 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007412#endif
7413#ifdef HAVE_TEMPNAM
7414 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7415#endif
7416#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007417 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007418#endif
Fred Drakec9680921999-12-13 16:37:25 +00007419#ifdef HAVE_CONFSTR
7420 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7421#endif
7422#ifdef HAVE_SYSCONF
7423 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7424#endif
7425#ifdef HAVE_FPATHCONF
7426 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7427#endif
7428#ifdef HAVE_PATHCONF
7429 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7430#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007431 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007432#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007433 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7434#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007435#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007436 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007437#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007438 {NULL, NULL} /* Sentinel */
7439};
7440
7441
Barry Warsaw4a342091996-12-19 23:50:02 +00007442static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007443ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007444{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007445 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007446}
7447
Guido van Rossumd48f2521997-12-05 22:19:34 +00007448#if defined(PYOS_OS2)
7449/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007450static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007451{
7452 APIRET rc;
7453 ULONG values[QSV_MAX+1];
7454 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007455 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007456
7457 Py_BEGIN_ALLOW_THREADS
7458 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7459 Py_END_ALLOW_THREADS
7460
7461 if (rc != NO_ERROR) {
7462 os2_error(rc);
7463 return -1;
7464 }
7465
Fred Drake4d1e64b2002-04-15 19:40:07 +00007466 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7467 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7468 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7469 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7470 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7471 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7472 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007473
7474 switch (values[QSV_VERSION_MINOR]) {
7475 case 0: ver = "2.00"; break;
7476 case 10: ver = "2.10"; break;
7477 case 11: ver = "2.11"; break;
7478 case 30: ver = "3.00"; break;
7479 case 40: ver = "4.00"; break;
7480 case 50: ver = "5.00"; break;
7481 default:
Tim Peters885d4572001-11-28 20:27:42 +00007482 PyOS_snprintf(tmp, sizeof(tmp),
7483 "%d-%d", values[QSV_VERSION_MAJOR],
7484 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007485 ver = &tmp[0];
7486 }
7487
7488 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007489 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007490 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007491
7492 /* Add Indicator of Which Drive was Used to Boot the System */
7493 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7494 tmp[1] = ':';
7495 tmp[2] = '\0';
7496
Fred Drake4d1e64b2002-04-15 19:40:07 +00007497 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007498}
7499#endif
7500
Barry Warsaw4a342091996-12-19 23:50:02 +00007501static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007502all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007503{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007504#ifdef F_OK
7505 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007507#ifdef R_OK
7508 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007509#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007510#ifdef W_OK
7511 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007512#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007513#ifdef X_OK
7514 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007515#endif
Fred Drakec9680921999-12-13 16:37:25 +00007516#ifdef NGROUPS_MAX
7517 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7518#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007519#ifdef TMP_MAX
7520 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7521#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007522#ifdef WCONTINUED
7523 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7524#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007525#ifdef WNOHANG
7526 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007527#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007528#ifdef WUNTRACED
7529 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7530#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007531#ifdef O_RDONLY
7532 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7533#endif
7534#ifdef O_WRONLY
7535 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7536#endif
7537#ifdef O_RDWR
7538 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7539#endif
7540#ifdef O_NDELAY
7541 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7542#endif
7543#ifdef O_NONBLOCK
7544 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7545#endif
7546#ifdef O_APPEND
7547 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7548#endif
7549#ifdef O_DSYNC
7550 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7551#endif
7552#ifdef O_RSYNC
7553 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7554#endif
7555#ifdef O_SYNC
7556 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7557#endif
7558#ifdef O_NOCTTY
7559 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7560#endif
7561#ifdef O_CREAT
7562 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7563#endif
7564#ifdef O_EXCL
7565 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7566#endif
7567#ifdef O_TRUNC
7568 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7569#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007570#ifdef O_BINARY
7571 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7572#endif
7573#ifdef O_TEXT
7574 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7575#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007576#ifdef O_LARGEFILE
7577 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7578#endif
7579
Tim Peters5aa91602002-01-30 05:46:57 +00007580/* MS Windows */
7581#ifdef O_NOINHERIT
7582 /* Don't inherit in child processes. */
7583 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7584#endif
7585#ifdef _O_SHORT_LIVED
7586 /* Optimize for short life (keep in memory). */
7587 /* MS forgot to define this one with a non-underscore form too. */
7588 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7589#endif
7590#ifdef O_TEMPORARY
7591 /* Automatically delete when last handle is closed. */
7592 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7593#endif
7594#ifdef O_RANDOM
7595 /* Optimize for random access. */
7596 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7597#endif
7598#ifdef O_SEQUENTIAL
7599 /* Optimize for sequential access. */
7600 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7601#endif
7602
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007603/* GNU extensions. */
7604#ifdef O_DIRECT
7605 /* Direct disk access. */
7606 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7607#endif
7608#ifdef O_DIRECTORY
7609 /* Must be a directory. */
7610 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7611#endif
7612#ifdef O_NOFOLLOW
7613 /* Do not follow links. */
7614 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7615#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007616
Barry Warsaw5676bd12003-01-07 20:57:09 +00007617 /* These come from sysexits.h */
7618#ifdef EX_OK
7619 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007620#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007621#ifdef EX_USAGE
7622 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007623#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007624#ifdef EX_DATAERR
7625 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007626#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007627#ifdef EX_NOINPUT
7628 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007629#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007630#ifdef EX_NOUSER
7631 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007632#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007633#ifdef EX_NOHOST
7634 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007635#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007636#ifdef EX_UNAVAILABLE
7637 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007638#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007639#ifdef EX_SOFTWARE
7640 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007641#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007642#ifdef EX_OSERR
7643 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007644#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007645#ifdef EX_OSFILE
7646 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007647#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007648#ifdef EX_CANTCREAT
7649 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007650#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007651#ifdef EX_IOERR
7652 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007653#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007654#ifdef EX_TEMPFAIL
7655 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007656#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007657#ifdef EX_PROTOCOL
7658 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007659#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007660#ifdef EX_NOPERM
7661 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007662#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007663#ifdef EX_CONFIG
7664 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007665#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007666#ifdef EX_NOTFOUND
7667 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007668#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007669
Guido van Rossum246bc171999-02-01 23:54:31 +00007670#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007671#if defined(PYOS_OS2) && defined(PYCC_GCC)
7672 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7673 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7674 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7675 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7676 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7677 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7678 if (ins(d, "P_PM", (long)P_PM)) return -1;
7679 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7680 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7681 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7682 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7683 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7684 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7685 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7686 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7687 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7688 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7689 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7690 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7691 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7692#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007693 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7694 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7695 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7696 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7697 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007698#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007699#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007700
Guido van Rossumd48f2521997-12-05 22:19:34 +00007701#if defined(PYOS_OS2)
7702 if (insertvalues(d)) return -1;
7703#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007704 return 0;
7705}
7706
7707
Tim Peters5aa91602002-01-30 05:46:57 +00007708#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007709#define INITFUNC initnt
7710#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007711
7712#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007713#define INITFUNC initos2
7714#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007715
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007716#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007717#define INITFUNC initposix
7718#define MODNAME "posix"
7719#endif
7720
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007721PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007722INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007723{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007724 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007725
Fred Drake4d1e64b2002-04-15 19:40:07 +00007726 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007727 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007728 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007729
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007730 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007731 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007732 Py_XINCREF(v);
7733 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007734 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007735 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007736
Fred Drake4d1e64b2002-04-15 19:40:07 +00007737 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007738 return;
7739
Fred Drake4d1e64b2002-04-15 19:40:07 +00007740 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007741 return;
7742
Fred Drake4d1e64b2002-04-15 19:40:07 +00007743 Py_INCREF(PyExc_OSError);
7744 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007745
Guido van Rossumb3d39562000-01-31 18:41:26 +00007746#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007747 if (posix_putenv_garbage == NULL)
7748 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007749#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007750
Guido van Rossum14648392001-12-08 18:02:58 +00007751 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007752 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7753 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7754 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007755 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007756 structseq_new = StatResultType.tp_new;
7757 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007758 Py_INCREF((PyObject*) &StatResultType);
7759 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007760
Guido van Rossum14648392001-12-08 18:02:58 +00007761 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007762 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007763 Py_INCREF((PyObject*) &StatVFSResultType);
7764 PyModule_AddObject(m, "statvfs_result",
7765 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007766}