blob: 9dea4b525c7245f824d52ac97f1d908b7f28561d [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 *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001316posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001317{
1318 char *ret;
1319 char buffer[L_ctermid];
1320
1321 if (!PyArg_ParseTuple(args, ":ctermid"))
1322 return NULL;
1323
Greg Wardb48bc172000-03-01 21:51:56 +00001324#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001325 ret = ctermid_r(buffer);
1326#else
1327 ret = ctermid(buffer);
1328#endif
1329 if (ret == NULL)
1330 return(posix_error());
1331 return(PyString_FromString(buffer));
1332}
1333#endif
1334
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001335PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001336"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001340posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001342#ifdef MS_WINDOWS
1343 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1344#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1345 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001346#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001347#ifdef __VMS
1348 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1349 NULL, NULL);
1350#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001352#endif
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001353#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354}
1355
Fred Drake4d1e64b2002-04-15 19:40:07 +00001356#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001358"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001359Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001360opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001361
1362static PyObject *
1363posix_fchdir(PyObject *self, PyObject *fdobj)
1364{
1365 return posix_fildes(fdobj, fchdir);
1366}
1367#endif /* HAVE_FCHDIR */
1368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001371"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001372Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001373
Barry Warsaw53699e91996-12-10 23:23:01 +00001374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001375posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001376{
Mark Hammondef8b6542001-05-13 08:04:26 +00001377 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001378 int i;
1379 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001380 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001381 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001382 return NULL;
1383 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001384 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001385 Py_END_ALLOW_THREADS
1386 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001387 return posix_error_with_allocated_filename(path);
1388 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001389 Py_INCREF(Py_None);
1390 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001391}
1392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
Martin v. Löwis244edc82001-10-04 22:44:26 +00001394#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001395PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001396"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001398
1399static PyObject *
1400posix_chroot(PyObject *self, PyObject *args)
1401{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001402 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001403}
1404#endif
1405
Guido van Rossum21142a01999-01-08 21:05:37 +00001406#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001408"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001409force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001410
1411static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001412posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001413{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001414 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001415}
1416#endif /* HAVE_FSYNC */
1417
1418#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001419
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001420#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001421extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1422#endif
1423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001424PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001425"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001426force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001427 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001428
1429static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001430posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001431{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001432 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001433}
1434#endif /* HAVE_FDATASYNC */
1435
1436
Fredrik Lundh10723342000-07-10 16:38:09 +00001437#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001438PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001439"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001441
Barry Warsaw53699e91996-12-10 23:23:01 +00001442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001443posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001444{
Mark Hammondef8b6542001-05-13 08:04:26 +00001445 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001446 int uid, gid;
1447 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001448 if (!PyArg_ParseTuple(args, "etii:chown",
1449 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001450 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001451 return NULL;
1452 Py_BEGIN_ALLOW_THREADS
1453 res = chown(path, (uid_t) uid, (gid_t) gid);
1454 Py_END_ALLOW_THREADS
1455 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001456 return posix_error_with_allocated_filename(path);
1457 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001458 Py_INCREF(Py_None);
1459 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001460}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001461#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001462
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001463#ifdef HAVE_LCHOWN
1464PyDoc_STRVAR(posix_lchown__doc__,
1465"lchown(path, uid, gid)\n\n\
1466Change the owner and group id of path to the numeric uid and gid.\n\
1467This function will not follow symbolic links.");
1468
1469static PyObject *
1470posix_lchown(PyObject *self, PyObject *args)
1471{
1472 char *path = NULL;
1473 int uid, gid;
1474 int res;
1475 if (!PyArg_ParseTuple(args, "etii:lchown",
1476 Py_FileSystemDefaultEncoding, &path,
1477 &uid, &gid))
1478 return NULL;
1479 Py_BEGIN_ALLOW_THREADS
1480 res = lchown(path, (uid_t) uid, (gid_t) gid);
1481 Py_END_ALLOW_THREADS
1482 if (res < 0)
1483 return posix_error_with_allocated_filename(path);
1484 PyMem_Free(path);
1485 Py_INCREF(Py_None);
1486 return Py_None;
1487}
1488#endif /* HAVE_LCHOWN */
1489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001490
Guido van Rossum36bc6801995-06-14 22:54:23 +00001491#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001492PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001493"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001494Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001495
Barry Warsaw53699e91996-12-10 23:23:01 +00001496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001497posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498{
1499 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001500 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001501 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001503 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001504#if defined(PYOS_OS2) && defined(PYCC_GCC)
1505 res = _getcwd2(buf, sizeof buf);
1506#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001507#if defined(__VMS)
1508 /* 0 = force Unix-style path if in the VMS DCL environment! */
1509 res = getcwd(buf, sizeof buf, 0);
1510#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001511 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001512#endif
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001513#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001514 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001515 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001516 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001517 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001518}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001519
Walter Dörwald3b918c32002-11-21 20:18:46 +00001520#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001521PyDoc_STRVAR(posix_getcwdu__doc__,
1522"getcwdu() -> path\n\n\
1523Return a unicode string representing the current working directory.");
1524
1525static PyObject *
1526posix_getcwdu(PyObject *self, PyObject *args)
1527{
1528 char buf[1026];
1529 char *res;
1530 if (!PyArg_ParseTuple(args, ":getcwd"))
1531 return NULL;
1532
1533#ifdef Py_WIN_WIDE_FILENAMES
1534 if (unicode_file_names()) {
1535 wchar_t *wres;
1536 wchar_t wbuf[1026];
1537 Py_BEGIN_ALLOW_THREADS
1538 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1539 Py_END_ALLOW_THREADS
1540 if (wres == NULL)
1541 return posix_error();
1542 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1543 }
1544#endif
1545
1546 Py_BEGIN_ALLOW_THREADS
1547#if defined(PYOS_OS2) && defined(PYCC_GCC)
1548 res = _getcwd2(buf, sizeof buf);
1549#else
1550 res = getcwd(buf, sizeof buf);
1551#endif
1552 Py_END_ALLOW_THREADS
1553 if (res == NULL)
1554 return posix_error();
1555 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1556}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001557#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001558#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001560
Guido van Rossumb6775db1994-08-01 11:34:53 +00001561#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001562PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001563"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001564Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001565
Barry Warsaw53699e91996-12-10 23:23:01 +00001566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001567posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001568{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001569 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001570}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001571#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001574PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001575"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001576Return a list containing the names of the entries in the directory.\n\
1577\n\
1578 path: path of directory to list\n\
1579\n\
1580The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001581entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001582
Barry Warsaw53699e91996-12-10 23:23:01 +00001583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001584posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001585{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001586 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001587 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001588#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001589
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001591 HANDLE hFindFile;
1592 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001593 /* MAX_PATH characters could mean a bigger encoded string */
1594 char namebuf[MAX_PATH*2+5];
1595 char *bufptr = namebuf;
1596 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001597
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001598#ifdef Py_WIN_WIDE_FILENAMES
1599 /* If on wide-character-capable OS see if argument
1600 is Unicode and if so use wide API. */
1601 if (unicode_file_names()) {
1602 PyUnicodeObject *po;
1603 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1604 WIN32_FIND_DATAW wFileData;
1605 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1606 Py_UNICODE wch;
1607 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1608 wnamebuf[MAX_PATH] = L'\0';
1609 len = wcslen(wnamebuf);
1610 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1611 if (wch != L'/' && wch != L'\\' && wch != L':')
1612 wnamebuf[len++] = L'/';
1613 wcscpy(wnamebuf + len, L"*.*");
1614 if ((d = PyList_New(0)) == NULL)
1615 return NULL;
1616 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1617 if (hFindFile == INVALID_HANDLE_VALUE) {
1618 errno = GetLastError();
1619 if (errno == ERROR_FILE_NOT_FOUND) {
1620 return d;
1621 }
1622 Py_DECREF(d);
1623 return win32_error_unicode("FindFirstFileW", wnamebuf);
1624 }
1625 do {
1626 if (wFileData.cFileName[0] == L'.' &&
1627 (wFileData.cFileName[1] == L'\0' ||
1628 wFileData.cFileName[1] == L'.' &&
1629 wFileData.cFileName[2] == L'\0'))
1630 continue;
1631 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1632 if (v == NULL) {
1633 Py_DECREF(d);
1634 d = NULL;
1635 break;
1636 }
1637 if (PyList_Append(d, v) != 0) {
1638 Py_DECREF(v);
1639 Py_DECREF(d);
1640 d = NULL;
1641 break;
1642 }
1643 Py_DECREF(v);
1644 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1645
1646 if (FindClose(hFindFile) == FALSE) {
1647 Py_DECREF(d);
1648 return win32_error_unicode("FindClose", wnamebuf);
1649 }
1650 return d;
1651 }
1652 /* Drop the argument parsing error as narrow strings
1653 are also valid. */
1654 PyErr_Clear();
1655 }
1656#endif
1657
Tim Peters5aa91602002-01-30 05:46:57 +00001658 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001659 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001660 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001661 if (len > 0) {
1662 char ch = namebuf[len-1];
1663 if (ch != SEP && ch != ALTSEP && ch != ':')
1664 namebuf[len++] = '/';
1665 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001666 strcpy(namebuf + len, "*.*");
1667
Barry Warsaw53699e91996-12-10 23:23:01 +00001668 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001669 return NULL;
1670
1671 hFindFile = FindFirstFile(namebuf, &FileData);
1672 if (hFindFile == INVALID_HANDLE_VALUE) {
1673 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001674 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001675 return d;
1676 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001677 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001678 }
1679 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001680 if (FileData.cFileName[0] == '.' &&
1681 (FileData.cFileName[1] == '\0' ||
1682 FileData.cFileName[1] == '.' &&
1683 FileData.cFileName[2] == '\0'))
1684 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001685 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001686 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 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 if (PyList_Append(d, v) != 0) {
1692 Py_DECREF(v);
1693 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001694 d = NULL;
1695 break;
1696 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001697 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001698 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1699
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001700 if (FindClose(hFindFile) == FALSE) {
1701 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001702 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001703 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001704
1705 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001706
Tim Peters0bb44a42000-09-15 07:44:49 +00001707#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001708
1709#ifndef MAX_PATH
1710#define MAX_PATH CCHMAXPATH
1711#endif
1712 char *name, *pt;
1713 int len;
1714 PyObject *d, *v;
1715 char namebuf[MAX_PATH+5];
1716 HDIR hdir = 1;
1717 ULONG srchcnt = 1;
1718 FILEFINDBUF3 ep;
1719 APIRET rc;
1720
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001721 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001722 return NULL;
1723 if (len >= MAX_PATH) {
1724 PyErr_SetString(PyExc_ValueError, "path too long");
1725 return NULL;
1726 }
1727 strcpy(namebuf, name);
1728 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001729 if (*pt == ALTSEP)
1730 *pt = SEP;
1731 if (namebuf[len-1] != SEP)
1732 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001733 strcpy(namebuf + len, "*.*");
1734
1735 if ((d = PyList_New(0)) == NULL)
1736 return NULL;
1737
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001738 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1739 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001740 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001741 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1742 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1743 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001744
1745 if (rc != NO_ERROR) {
1746 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001747 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001748 }
1749
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001750 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001751 do {
1752 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001753 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001754 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001755
1756 strcpy(namebuf, ep.achName);
1757
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001758 /* Leave Case of Name Alone -- In Native Form */
1759 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001760
1761 v = PyString_FromString(namebuf);
1762 if (v == NULL) {
1763 Py_DECREF(d);
1764 d = NULL;
1765 break;
1766 }
1767 if (PyList_Append(d, v) != 0) {
1768 Py_DECREF(v);
1769 Py_DECREF(d);
1770 d = NULL;
1771 break;
1772 }
1773 Py_DECREF(v);
1774 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1775 }
1776
1777 return d;
1778#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001779
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001780 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001781 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001782 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001783 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001784 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001785 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001786 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001787 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001788 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001789 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001790 closedir(dirp);
1791 return NULL;
1792 }
1793 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001794 if (ep->d_name[0] == '.' &&
1795 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001796 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001797 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001798 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001799 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001800 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001801 d = NULL;
1802 break;
1803 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001804 if (PyList_Append(d, v) != 0) {
1805 Py_DECREF(v);
1806 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001807 d = NULL;
1808 break;
1809 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001810 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001811 }
1812 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001813
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001814 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001815
Tim Peters0bb44a42000-09-15 07:44:49 +00001816#endif /* which OS */
1817} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001818
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001819#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001820/* A helper function for abspath on win32 */
1821static PyObject *
1822posix__getfullpathname(PyObject *self, PyObject *args)
1823{
1824 /* assume encoded strings wont more than double no of chars */
1825 char inbuf[MAX_PATH*2];
1826 char *inbufp = inbuf;
1827 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1828 char outbuf[MAX_PATH*2];
1829 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001830#ifdef Py_WIN_WIDE_FILENAMES
1831 if (unicode_file_names()) {
1832 PyUnicodeObject *po;
1833 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1834 Py_UNICODE woutbuf[MAX_PATH*2];
1835 Py_UNICODE *wtemp;
1836 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1837 sizeof(woutbuf)/sizeof(woutbuf[0]),
1838 woutbuf, &wtemp))
1839 return win32_error("GetFullPathName", "");
1840 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1841 }
1842 /* Drop the argument parsing error as narrow strings
1843 are also valid. */
1844 PyErr_Clear();
1845 }
1846#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001847 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1848 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001849 &insize))
1850 return NULL;
1851 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1852 outbuf, &temp))
1853 return win32_error("GetFullPathName", inbuf);
1854 return PyString_FromString(outbuf);
1855} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001856#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001857
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001858PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001859"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001860Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001861
Barry Warsaw53699e91996-12-10 23:23:01 +00001862static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001863posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001864{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001865 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001866 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001867 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001868
1869#ifdef Py_WIN_WIDE_FILENAMES
1870 if (unicode_file_names()) {
1871 PyUnicodeObject *po;
1872 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1873 Py_BEGIN_ALLOW_THREADS
1874 /* PyUnicode_AS_UNICODE OK without thread lock as
1875 it is a simple dereference. */
1876 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1877 Py_END_ALLOW_THREADS
1878 if (res < 0)
1879 return posix_error();
1880 Py_INCREF(Py_None);
1881 return Py_None;
1882 }
1883 /* Drop the argument parsing error as narrow strings
1884 are also valid. */
1885 PyErr_Clear();
1886 }
1887#endif
1888
Tim Peters5aa91602002-01-30 05:46:57 +00001889 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001890 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001891 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001893#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001894 res = mkdir(path);
1895#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001896 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001897#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001899 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001900 return posix_error_with_allocated_filename(path);
1901 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001902 Py_INCREF(Py_None);
1903 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001904}
1905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001906
Guido van Rossumb6775db1994-08-01 11:34:53 +00001907#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001908#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1909#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1910#include <sys/resource.h>
1911#endif
1912#endif
1913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001914PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001915"nice(inc) -> new_priority\n\n\
1916Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001917
Barry Warsaw53699e91996-12-10 23:23:01 +00001918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001919posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001920{
1921 int increment, value;
1922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001923 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001924 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001925
1926 /* There are two flavours of 'nice': one that returns the new
1927 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001928 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1929 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001930
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001931 If we are of the nice family that returns the new priority, we
1932 need to clear errno before the call, and check if errno is filled
1933 before calling posix_error() on a returnvalue of -1, because the
1934 -1 may be the actual new priority! */
1935
1936 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001937 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001938#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001939 if (value == 0)
1940 value = getpriority(PRIO_PROCESS, 0);
1941#endif
1942 if (value == -1 && errno != 0)
1943 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001944 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001945 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001946}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001947#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001950PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001951"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001952Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953
Barry Warsaw53699e91996-12-10 23:23:01 +00001954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001955posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001956{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001957#ifdef MS_WINDOWS
1958 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1959#else
1960 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1961#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001962}
1963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001965PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001966"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001967Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001970posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001971{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001972#ifdef MS_WINDOWS
1973 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1974#else
1975 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1976#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001977}
1978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001981"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001987#ifdef MS_WINDOWS
1988 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1989#else
1990 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1991#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001992}
1993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001995#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001997"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001998Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Barry Warsaw53699e91996-12-10 23:23:01 +00002000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002002{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002003 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002004 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002005 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002006 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002008 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002009 Py_END_ALLOW_THREADS
2010 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002011}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002012#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002015PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002016"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002017Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002018
Barry Warsaw53699e91996-12-10 23:23:01 +00002019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002020posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002021{
2022 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002023 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002024 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002025 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002026 if (i < 0)
2027 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002028 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029}
2030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002033"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002036PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002037"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002038Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002039
Barry Warsaw53699e91996-12-10 23:23:01 +00002040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002041posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002043#ifdef MS_WINDOWS
2044 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2045#else
2046 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2047#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002048}
2049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Guido van Rossumb6775db1994-08-01 11:34:53 +00002051#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002053"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Barry Warsaw53699e91996-12-10 23:23:01 +00002056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002057posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002058{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002059 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002060 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002061 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002062 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002063 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002064 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002065 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002066 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002067 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002068 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002069 u.sysname,
2070 u.nodename,
2071 u.release,
2072 u.version,
2073 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002074}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002076
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002077static int
2078extract_time(PyObject *t, long* sec, long* usec)
2079{
2080 long intval;
2081 if (PyFloat_Check(t)) {
2082 double tval = PyFloat_AsDouble(t);
2083 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2084 if (!intobj)
2085 return -1;
2086 intval = PyInt_AsLong(intobj);
2087 Py_DECREF(intobj);
2088 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002089 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002090 if (*usec < 0)
2091 /* If rounding gave us a negative number,
2092 truncate. */
2093 *usec = 0;
2094 return 0;
2095 }
2096 intval = PyInt_AsLong(t);
2097 if (intval == -1 && PyErr_Occurred())
2098 return -1;
2099 *sec = intval;
2100 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002101 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002102}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002104PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002105"utime(path, (atime, utime))\n\
2106utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002107Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002109
Barry Warsaw53699e91996-12-10 23:23:01 +00002110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002111posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002112{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002113 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002114 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002115 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002116 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002117
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002118#if defined(HAVE_UTIMES)
2119 struct timeval buf[2];
2120#define ATIME buf[0].tv_sec
2121#define MTIME buf[1].tv_sec
2122#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002123/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002124 struct utimbuf buf;
2125#define ATIME buf.actime
2126#define MTIME buf.modtime
2127#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002128#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002129 time_t buf[2];
2130#define ATIME buf[0]
2131#define MTIME buf[1]
2132#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002133#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002134
Barry Warsaw3cef8562000-05-01 16:17:24 +00002135 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002136 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002137 if (arg == Py_None) {
2138 /* optional time values not given */
2139 Py_BEGIN_ALLOW_THREADS
2140 res = utime(path, NULL);
2141 Py_END_ALLOW_THREADS
2142 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002143 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002144 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002145 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002146 return NULL;
2147 }
2148 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002149 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2150 &atime, &ausec) == -1)
2151 return NULL;
2152 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2153 &mtime, &musec) == -1)
2154 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002155 ATIME = atime;
2156 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002157#ifdef HAVE_UTIMES
2158 buf[0].tv_usec = ausec;
2159 buf[1].tv_usec = musec;
2160 Py_BEGIN_ALLOW_THREADS
2161 res = utimes(path, buf);
2162 Py_END_ALLOW_THREADS
2163#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002164 Py_BEGIN_ALLOW_THREADS
2165 res = utime(path, UTIME_ARG);
2166 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002167#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002168 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002169 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002170 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002171 Py_INCREF(Py_None);
2172 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002173#undef UTIME_ARG
2174#undef ATIME
2175#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002176}
2177
Guido van Rossum85e3b011991-06-03 12:42:10 +00002178
Guido van Rossum3b066191991-06-04 19:40:25 +00002179/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002181PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002182"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002183Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002184
Barry Warsaw53699e91996-12-10 23:23:01 +00002185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002186posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187{
2188 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002189 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002190 return NULL;
2191 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002192 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193}
2194
Martin v. Löwis114619e2002-10-07 06:44:21 +00002195#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2196static void
2197free_string_array(char **array, int count)
2198{
2199 int i;
2200 for (i = 0; i < count; i++)
2201 PyMem_Free(array[i]);
2202 PyMem_DEL(array);
2203}
2204#endif
2205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002207#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002208PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002209"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210Execute an executable path with arguments, replacing current process.\n\
2211\n\
2212 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002213 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002214
Barry Warsaw53699e91996-12-10 23:23:01 +00002215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002216posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002217{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002218 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002219 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002220 char **argvlist;
2221 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002222 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002223
Guido van Rossum89b33251993-10-22 14:26:06 +00002224 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002225 argv is a list or tuple of strings. */
2226
Martin v. Löwis114619e2002-10-07 06:44:21 +00002227 if (!PyArg_ParseTuple(args, "etO:execv",
2228 Py_FileSystemDefaultEncoding,
2229 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002230 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002231 if (PyList_Check(argv)) {
2232 argc = PyList_Size(argv);
2233 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002234 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002235 else if (PyTuple_Check(argv)) {
2236 argc = PyTuple_Size(argv);
2237 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002238 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002239 else {
Fred Drake661ea262000-10-24 19:57:45 +00002240 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002241 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002242 return NULL;
2243 }
2244
2245 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002246 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002247 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002248 return NULL;
2249 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002250
Barry Warsaw53699e91996-12-10 23:23:01 +00002251 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002252 if (argvlist == NULL) {
2253 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002254 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002255 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002256 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002257 if (!PyArg_Parse((*getitem)(argv, i), "et",
2258 Py_FileSystemDefaultEncoding,
2259 &argvlist[i])) {
2260 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002261 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002262 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002263 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002264 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002265
Guido van Rossum85e3b011991-06-03 12:42:10 +00002266 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002267 }
2268 argvlist[argc] = NULL;
2269
Guido van Rossumb6775db1994-08-01 11:34:53 +00002270#ifdef BAD_EXEC_PROTOTYPES
2271 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002272#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002273 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002274#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002275
Guido van Rossum85e3b011991-06-03 12:42:10 +00002276 /* If we get here it's definitely an error */
2277
Martin v. Löwis114619e2002-10-07 06:44:21 +00002278 free_string_array(argvlist, argc);
2279 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002280 return posix_error();
2281}
2282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002284PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002285"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002286Execute a path with arguments and environment, replacing current process.\n\
2287\n\
2288 path: path of executable file\n\
2289 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002290 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002291
Barry Warsaw53699e91996-12-10 23:23:01 +00002292static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002293posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002294{
2295 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002296 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002297 char **argvlist;
2298 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002299 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002300 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002301 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002302 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002303
2304 /* execve has three arguments: (path, argv, env), where
2305 argv is a list or tuple of strings and env is a dictionary
2306 like posix.environ. */
2307
Martin v. Löwis114619e2002-10-07 06:44:21 +00002308 if (!PyArg_ParseTuple(args, "etOO:execve",
2309 Py_FileSystemDefaultEncoding,
2310 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002311 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002312 if (PyList_Check(argv)) {
2313 argc = PyList_Size(argv);
2314 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002315 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002316 else if (PyTuple_Check(argv)) {
2317 argc = PyTuple_Size(argv);
2318 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002319 }
2320 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002321 PyErr_SetString(PyExc_TypeError,
2322 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002323 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002324 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002325 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002326 PyErr_SetString(PyExc_TypeError,
2327 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002328 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002329 }
2330
Guido van Rossum50422b42000-04-26 20:34:28 +00002331 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002332 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002333 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002335 }
2336
Barry Warsaw53699e91996-12-10 23:23:01 +00002337 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002338 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002340 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002341 }
2342 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002343 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002345 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002346 &argvlist[i]))
2347 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002348 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002349 goto fail_1;
2350 }
2351 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002352 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002353 argvlist[argc] = NULL;
2354
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002355 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002356 if (i < 0)
2357 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002358 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002359 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002360 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002361 goto fail_1;
2362 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002363 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002364 keys = PyMapping_Keys(env);
2365 vals = PyMapping_Values(env);
2366 if (!keys || !vals)
2367 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002368 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2369 PyErr_SetString(PyExc_TypeError,
2370 "execve(): env.keys() or env.values() is not a list");
2371 goto fail_2;
2372 }
Tim Peters5aa91602002-01-30 05:46:57 +00002373
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002374 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002375 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002376 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002377
2378 key = PyList_GetItem(keys, pos);
2379 val = PyList_GetItem(vals, pos);
2380 if (!key || !val)
2381 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002382
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002383 if (!PyArg_Parse(
2384 key,
2385 "s;execve() arg 3 contains a non-string key",
2386 &k) ||
2387 !PyArg_Parse(
2388 val,
2389 "s;execve() arg 3 contains a non-string value",
2390 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002391 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002392 goto fail_2;
2393 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002394
2395#if defined(PYOS_OS2)
2396 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2397 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2398#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002399 len = PyString_Size(key) + PyString_Size(val) + 2;
2400 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002401 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002402 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002403 goto fail_2;
2404 }
Tim Petersc8996f52001-12-03 20:41:00 +00002405 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002406 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002407#if defined(PYOS_OS2)
2408 }
2409#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002410 }
2411 envlist[envc] = 0;
2412
Guido van Rossumb6775db1994-08-01 11:34:53 +00002413
2414#ifdef BAD_EXEC_PROTOTYPES
2415 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002416#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002417 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002418#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002419
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002420 /* If we get here it's definitely an error */
2421
2422 (void) posix_error();
2423
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002424 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002425 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002426 PyMem_DEL(envlist[envc]);
2427 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002428 fail_1:
2429 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002430 Py_XDECREF(vals);
2431 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002432 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002433 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002434 return NULL;
2435}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002436#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002437
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002438
Guido van Rossuma1065681999-01-25 23:20:23 +00002439#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002440PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002441"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002442Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002443\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002444 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002445 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002446 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002447
2448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002449posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002450{
2451 char *path;
2452 PyObject *argv;
2453 char **argvlist;
2454 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002455 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002456 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002457
2458 /* spawnv has three arguments: (mode, path, argv), where
2459 argv is a list or tuple of strings. */
2460
Martin v. Löwis114619e2002-10-07 06:44:21 +00002461 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2462 Py_FileSystemDefaultEncoding,
2463 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002464 return NULL;
2465 if (PyList_Check(argv)) {
2466 argc = PyList_Size(argv);
2467 getitem = PyList_GetItem;
2468 }
2469 else if (PyTuple_Check(argv)) {
2470 argc = PyTuple_Size(argv);
2471 getitem = PyTuple_GetItem;
2472 }
2473 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002474 PyErr_SetString(PyExc_TypeError,
2475 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002476 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002477 return NULL;
2478 }
2479
2480 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002481 if (argvlist == NULL) {
2482 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002483 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002484 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002485 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002486 if (!PyArg_Parse((*getitem)(argv, i), "et",
2487 Py_FileSystemDefaultEncoding,
2488 &argvlist[i])) {
2489 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002490 PyErr_SetString(
2491 PyExc_TypeError,
2492 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002493 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002494 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002495 }
2496 }
2497 argvlist[argc] = NULL;
2498
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002499#if defined(PYOS_OS2) && defined(PYCC_GCC)
2500 Py_BEGIN_ALLOW_THREADS
2501 spawnval = spawnv(mode, path, argvlist);
2502 Py_END_ALLOW_THREADS
2503#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002504 if (mode == _OLD_P_OVERLAY)
2505 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002506
Tim Peters25059d32001-12-07 20:35:43 +00002507 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002508 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002509 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002510#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002511
Martin v. Löwis114619e2002-10-07 06:44:21 +00002512 free_string_array(argvlist, argc);
2513 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002514
Fred Drake699f3522000-06-29 21:12:41 +00002515 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002516 return posix_error();
2517 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002518#if SIZEOF_LONG == SIZEOF_VOID_P
2519 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002520#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002521 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002522#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002523}
2524
2525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002526PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002527"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002528Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002529\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002530 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002531 path: path of executable file\n\
2532 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002533 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002534
2535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002536posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002537{
2538 char *path;
2539 PyObject *argv, *env;
2540 char **argvlist;
2541 char **envlist;
2542 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2543 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002544 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002545 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002546 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002547
2548 /* spawnve has four arguments: (mode, path, argv, env), where
2549 argv is a list or tuple of strings and env is a dictionary
2550 like posix.environ. */
2551
Martin v. Löwis114619e2002-10-07 06:44:21 +00002552 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2553 Py_FileSystemDefaultEncoding,
2554 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002555 return NULL;
2556 if (PyList_Check(argv)) {
2557 argc = PyList_Size(argv);
2558 getitem = PyList_GetItem;
2559 }
2560 else if (PyTuple_Check(argv)) {
2561 argc = PyTuple_Size(argv);
2562 getitem = PyTuple_GetItem;
2563 }
2564 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002565 PyErr_SetString(PyExc_TypeError,
2566 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002567 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002568 }
2569 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002570 PyErr_SetString(PyExc_TypeError,
2571 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002572 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002573 }
2574
2575 argvlist = PyMem_NEW(char *, argc+1);
2576 if (argvlist == NULL) {
2577 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002578 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002579 }
2580 for (i = 0; i < argc; i++) {
2581 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002582 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002583 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002584 &argvlist[i]))
2585 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002587 goto fail_1;
2588 }
2589 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002590 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002591 argvlist[argc] = NULL;
2592
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002593 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002594 if (i < 0)
2595 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002596 envlist = PyMem_NEW(char *, i + 1);
2597 if (envlist == NULL) {
2598 PyErr_NoMemory();
2599 goto fail_1;
2600 }
2601 envc = 0;
2602 keys = PyMapping_Keys(env);
2603 vals = PyMapping_Values(env);
2604 if (!keys || !vals)
2605 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002606 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2607 PyErr_SetString(PyExc_TypeError,
2608 "spawnve(): env.keys() or env.values() is not a list");
2609 goto fail_2;
2610 }
Tim Peters5aa91602002-01-30 05:46:57 +00002611
Guido van Rossuma1065681999-01-25 23:20:23 +00002612 for (pos = 0; pos < i; pos++) {
2613 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002614 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002615
2616 key = PyList_GetItem(keys, pos);
2617 val = PyList_GetItem(vals, pos);
2618 if (!key || !val)
2619 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002620
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002621 if (!PyArg_Parse(
2622 key,
2623 "s;spawnve() arg 3 contains a non-string key",
2624 &k) ||
2625 !PyArg_Parse(
2626 val,
2627 "s;spawnve() arg 3 contains a non-string value",
2628 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002629 {
2630 goto fail_2;
2631 }
Tim Petersc8996f52001-12-03 20:41:00 +00002632 len = PyString_Size(key) + PyString_Size(val) + 2;
2633 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002634 if (p == NULL) {
2635 PyErr_NoMemory();
2636 goto fail_2;
2637 }
Tim Petersc8996f52001-12-03 20:41:00 +00002638 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002639 envlist[envc++] = p;
2640 }
2641 envlist[envc] = 0;
2642
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002643#if defined(PYOS_OS2) && defined(PYCC_GCC)
2644 Py_BEGIN_ALLOW_THREADS
2645 spawnval = spawnve(mode, path, argvlist, envlist);
2646 Py_END_ALLOW_THREADS
2647#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002648 if (mode == _OLD_P_OVERLAY)
2649 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002650
2651 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002652 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002653 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002654#endif
Tim Peters25059d32001-12-07 20:35:43 +00002655
Fred Drake699f3522000-06-29 21:12:41 +00002656 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002657 (void) posix_error();
2658 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002659#if SIZEOF_LONG == SIZEOF_VOID_P
2660 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002661#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002662 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002663#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002664
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002665 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002666 while (--envc >= 0)
2667 PyMem_DEL(envlist[envc]);
2668 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002669 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002671 Py_XDECREF(vals);
2672 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002673 fail_0:
2674 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002675 return res;
2676}
2677#endif /* HAVE_SPAWNV */
2678
2679
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002680#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002681PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002682"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002683Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2684\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002685Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002686
2687static PyObject *
2688posix_fork1(self, args)
2689 PyObject *self;
2690 PyObject *args;
2691{
2692 int pid;
2693 if (!PyArg_ParseTuple(args, ":fork1"))
2694 return NULL;
2695 pid = fork1();
2696 if (pid == -1)
2697 return posix_error();
2698 PyOS_AfterFork();
2699 return PyInt_FromLong((long)pid);
2700}
2701#endif
2702
2703
Guido van Rossumad0ee831995-03-01 10:34:45 +00002704#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002705PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002706"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002711posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002712{
2713 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002715 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002716 pid = fork();
2717 if (pid == -1)
2718 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002719 if (pid == 0)
2720 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002721 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002722}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002723#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002724
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002725#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002726#ifdef HAVE_PTY_H
2727#include <pty.h>
2728#else
2729#ifdef HAVE_LIBUTIL_H
2730#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002731#endif /* HAVE_LIBUTIL_H */
2732#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002733#ifdef HAVE_STROPTS_H
2734#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002735#endif
2736#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002737
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002738#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002742
2743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002744posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002745{
2746 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002747#ifndef HAVE_OPENPTY
2748 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002749#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002750#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002751 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002752#ifdef sun
2753 extern char *ptsname();
2754#endif
2755#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002756
Fred Drake8cef4cf2000-06-28 16:40:38 +00002757 if (!PyArg_ParseTuple(args, ":openpty"))
2758 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002759
2760#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002761 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2762 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002763#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002764 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2765 if (slave_name == NULL)
2766 return posix_error();
2767
2768 slave_fd = open(slave_name, O_RDWR);
2769 if (slave_fd < 0)
2770 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002771#else
2772 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2773 if (master_fd < 0)
2774 return posix_error();
2775 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002776 /* change permission of slave */
2777 if (grantpt(master_fd) < 0) {
2778 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002779 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002780 }
2781 /* unlock slave */
2782 if (unlockpt(master_fd) < 0) {
2783 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002784 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002785 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002786 signal(SIGCHLD, sig_saved);
2787 slave_name = ptsname(master_fd); /* get name of slave */
2788 if (slave_name == NULL)
2789 return posix_error();
2790 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2791 if (slave_fd < 0)
2792 return posix_error();
2793#ifndef __CYGWIN__
2794 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2795 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002796#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002797 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002798#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002799#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002800#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002801
Fred Drake8cef4cf2000-06-28 16:40:38 +00002802 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002803
Fred Drake8cef4cf2000-06-28 16:40:38 +00002804}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002805#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002806
2807#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002808PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002809"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002810Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2811Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002812To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002813
2814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002815posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002816{
2817 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002818
Fred Drake8cef4cf2000-06-28 16:40:38 +00002819 if (!PyArg_ParseTuple(args, ":forkpty"))
2820 return NULL;
2821 pid = forkpty(&master_fd, NULL, NULL, NULL);
2822 if (pid == -1)
2823 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002824 if (pid == 0)
2825 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002826 return Py_BuildValue("(ii)", pid, master_fd);
2827}
2828#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002829
Guido van Rossumad0ee831995-03-01 10:34:45 +00002830#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002831PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002832"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002833Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002834
Barry Warsaw53699e91996-12-10 23:23:01 +00002835static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002836posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002837{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002838 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002839 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002840 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002841}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002842#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002844
Guido van Rossumad0ee831995-03-01 10:34:45 +00002845#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002847"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002849
Barry Warsaw53699e91996-12-10 23:23:01 +00002850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002851posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002852{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002853 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002854 return NULL;
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 *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002866posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002867{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002868 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002869 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002870 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002871}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002872#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002880posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002881{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002882 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002883 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002884 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002885}
2886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Fred Drakec9680921999-12-13 16:37:25 +00002888#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002890"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002892
2893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002894posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002895{
2896 PyObject *result = NULL;
2897
2898 if (PyArg_ParseTuple(args, ":getgroups")) {
2899#ifdef NGROUPS_MAX
2900#define MAX_GROUPS NGROUPS_MAX
2901#else
2902 /* defined to be 16 on Solaris7, so this should be a small number */
2903#define MAX_GROUPS 64
2904#endif
2905 gid_t grouplist[MAX_GROUPS];
2906 int n;
2907
2908 n = getgroups(MAX_GROUPS, grouplist);
2909 if (n < 0)
2910 posix_error();
2911 else {
2912 result = PyList_New(n);
2913 if (result != NULL) {
2914 PyObject *o;
2915 int i;
2916 for (i = 0; i < n; ++i) {
2917 o = PyInt_FromLong((long)grouplist[i]);
2918 if (o == NULL) {
2919 Py_DECREF(result);
2920 result = NULL;
2921 break;
2922 }
2923 PyList_SET_ITEM(result, i, o);
2924 }
2925 }
2926 }
2927 }
2928 return result;
2929}
2930#endif
2931
Martin v. Löwis606edc12002-06-13 21:09:11 +00002932#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002933PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002934"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002935Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002936
2937static PyObject *
2938posix_getpgid(PyObject *self, PyObject *args)
2939{
2940 int pid, pgid;
2941 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2942 return NULL;
2943 pgid = getpgid(pid);
2944 if (pgid < 0)
2945 return posix_error();
2946 return PyInt_FromLong((long)pgid);
2947}
2948#endif /* HAVE_GETPGID */
2949
2950
Guido van Rossumb6775db1994-08-01 11:34:53 +00002951#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002952PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002953"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002957posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002958{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002959 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002960 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002961#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002962 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002963#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002964 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002965#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002966}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002967#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Guido van Rossumb6775db1994-08-01 11:34:53 +00002970#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002971PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002972"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002973Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002974
Barry Warsaw53699e91996-12-10 23:23:01 +00002975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002976posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002977{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002978 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002979 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002980#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002981 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002982#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002983 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002984#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002985 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002986 Py_INCREF(Py_None);
2987 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002988}
2989
Guido van Rossumb6775db1994-08-01 11:34:53 +00002990#endif /* HAVE_SETPGRP */
2991
Guido van Rossumad0ee831995-03-01 10:34:45 +00002992#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002994"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002995Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996
Barry Warsaw53699e91996-12-10 23:23:01 +00002997static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002998posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002999{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003000 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003001 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003002 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003003}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003004#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003006
Fred Drake12c6e2d1999-12-14 21:25:03 +00003007#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003009"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003010Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003011
3012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003013posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003014{
3015 PyObject *result = NULL;
3016
3017 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00003018 char *name;
3019 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003020
Fred Drakea30680b2000-12-06 21:24:28 +00003021 errno = 0;
3022 name = getlogin();
3023 if (name == NULL) {
3024 if (errno)
3025 posix_error();
3026 else
3027 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003028 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003029 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003030 else
3031 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003032 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003033 }
3034 return result;
3035}
3036#endif
3037
Guido van Rossumad0ee831995-03-01 10:34:45 +00003038#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003039PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003040"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003041Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003042
Barry Warsaw53699e91996-12-10 23:23:01 +00003043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003044posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003045{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003046 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00003047 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003049}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003050#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003052
Guido van Rossumad0ee831995-03-01 10:34:45 +00003053#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003054PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003055"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003056Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003057
Barry Warsaw53699e91996-12-10 23:23:01 +00003058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003059posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003060{
3061 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003062 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003063 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003064#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003065 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3066 APIRET rc;
3067 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003068 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003069
3070 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3071 APIRET rc;
3072 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003073 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003074
3075 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003076 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003077#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003078 if (kill(pid, sig) == -1)
3079 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003080#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003081 Py_INCREF(Py_None);
3082 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003083}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003084#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003085
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003086#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003087PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003088"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003090
3091static PyObject *
3092posix_killpg(PyObject *self, PyObject *args)
3093{
3094 int pgid, sig;
3095 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3096 return NULL;
3097 if (killpg(pgid, sig) == -1)
3098 return posix_error();
3099 Py_INCREF(Py_None);
3100 return Py_None;
3101}
3102#endif
3103
Guido van Rossumc0125471996-06-28 18:55:32 +00003104#ifdef HAVE_PLOCK
3105
3106#ifdef HAVE_SYS_LOCK_H
3107#include <sys/lock.h>
3108#endif
3109
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003110PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003111"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003112Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113
Barry Warsaw53699e91996-12-10 23:23:01 +00003114static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003115posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003116{
3117 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003118 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003119 return NULL;
3120 if (plock(op) == -1)
3121 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003122 Py_INCREF(Py_None);
3123 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003124}
3125#endif
3126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003127
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003128#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003129PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003130"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003133#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003134#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003135static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003136async_system(const char *command)
3137{
3138 char *p, errormsg[256], args[1024];
3139 RESULTCODES rcodes;
3140 APIRET rc;
3141 char *shell = getenv("COMSPEC");
3142 if (!shell)
3143 shell = "cmd";
3144
3145 strcpy(args, shell);
3146 p = &args[ strlen(args)+1 ];
3147 strcpy(p, "/c ");
3148 strcat(p, command);
3149 p += strlen(p) + 1;
3150 *p = '\0';
3151
3152 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003153 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003154 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003155 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003156 &rcodes, shell);
3157 return rc;
3158}
3159
Guido van Rossumd48f2521997-12-05 22:19:34 +00003160static FILE *
3161popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003162{
3163 HFILE rhan, whan;
3164 FILE *retfd = NULL;
3165 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3166
Guido van Rossumd48f2521997-12-05 22:19:34 +00003167 if (rc != NO_ERROR) {
3168 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003169 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003170 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003171
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003172 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3173 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003174
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003175 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3176 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003177
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003178 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3179 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003180
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003181 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003182 }
3183
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003184 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3185 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003186
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003187 if (rc == NO_ERROR)
3188 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3189
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003190 close(oldfd); /* And Close Saved STDOUT Handle */
3191 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003192
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003193 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3194 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003195
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003196 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3197 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003198
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003199 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3200 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003201
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003202 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003203 }
3204
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003205 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3206 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003207
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003208 if (rc == NO_ERROR)
3209 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3210
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003211 close(oldfd); /* And Close Saved STDIN Handle */
3212 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003213
Guido van Rossumd48f2521997-12-05 22:19:34 +00003214 } else {
3215 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003216 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003217 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003218}
3219
3220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003221posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003222{
3223 char *name;
3224 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003225 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003226 FILE *fp;
3227 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003228 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003229 return NULL;
3230 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003231 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003232 Py_END_ALLOW_THREADS
3233 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003234 return os2_error(err);
3235
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003236 f = PyFile_FromFile(fp, name, mode, fclose);
3237 if (f != NULL)
3238 PyFile_SetBufSize(f, bufsize);
3239 return f;
3240}
3241
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003242#elif defined(PYCC_GCC)
3243
3244/* standard posix version of popen() support */
3245static PyObject *
3246posix_popen(PyObject *self, PyObject *args)
3247{
3248 char *name;
3249 char *mode = "r";
3250 int bufsize = -1;
3251 FILE *fp;
3252 PyObject *f;
3253 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3254 return NULL;
3255 Py_BEGIN_ALLOW_THREADS
3256 fp = popen(name, mode);
3257 Py_END_ALLOW_THREADS
3258 if (fp == NULL)
3259 return posix_error();
3260 f = PyFile_FromFile(fp, name, mode, pclose);
3261 if (f != NULL)
3262 PyFile_SetBufSize(f, bufsize);
3263 return f;
3264}
3265
3266/* fork() under OS/2 has lots'o'warts
3267 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3268 * most of this code is a ripoff of the win32 code, but using the
3269 * capabilities of EMX's C library routines
3270 */
3271
3272/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3273#define POPEN_1 1
3274#define POPEN_2 2
3275#define POPEN_3 3
3276#define POPEN_4 4
3277
3278static PyObject *_PyPopen(char *, int, int, int);
3279static int _PyPclose(FILE *file);
3280
3281/*
3282 * Internal dictionary mapping popen* file pointers to process handles,
3283 * for use when retrieving the process exit code. See _PyPclose() below
3284 * for more information on this dictionary's use.
3285 */
3286static PyObject *_PyPopenProcs = NULL;
3287
3288/* os2emx version of popen2()
3289 *
3290 * The result of this function is a pipe (file) connected to the
3291 * process's stdin, and a pipe connected to the process's stdout.
3292 */
3293
3294static PyObject *
3295os2emx_popen2(PyObject *self, PyObject *args)
3296{
3297 PyObject *f;
3298 int tm=0;
3299
3300 char *cmdstring;
3301 char *mode = "t";
3302 int bufsize = -1;
3303 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3304 return NULL;
3305
3306 if (*mode == 't')
3307 tm = O_TEXT;
3308 else if (*mode != 'b') {
3309 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3310 return NULL;
3311 } else
3312 tm = O_BINARY;
3313
3314 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3315
3316 return f;
3317}
3318
3319/*
3320 * Variation on os2emx.popen2
3321 *
3322 * The result of this function is 3 pipes - the process's stdin,
3323 * stdout and stderr
3324 */
3325
3326static PyObject *
3327os2emx_popen3(PyObject *self, PyObject *args)
3328{
3329 PyObject *f;
3330 int tm = 0;
3331
3332 char *cmdstring;
3333 char *mode = "t";
3334 int bufsize = -1;
3335 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3336 return NULL;
3337
3338 if (*mode == 't')
3339 tm = O_TEXT;
3340 else if (*mode != 'b') {
3341 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3342 return NULL;
3343 } else
3344 tm = O_BINARY;
3345
3346 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3347
3348 return f;
3349}
3350
3351/*
3352 * Variation on os2emx.popen2
3353 *
3354 * The result of this function is 2 pipes - the processes stdin,
3355 * and stdout+stderr combined as a single pipe.
3356 */
3357
3358static PyObject *
3359os2emx_popen4(PyObject *self, PyObject *args)
3360{
3361 PyObject *f;
3362 int tm = 0;
3363
3364 char *cmdstring;
3365 char *mode = "t";
3366 int bufsize = -1;
3367 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3368 return NULL;
3369
3370 if (*mode == 't')
3371 tm = O_TEXT;
3372 else if (*mode != 'b') {
3373 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3374 return NULL;
3375 } else
3376 tm = O_BINARY;
3377
3378 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3379
3380 return f;
3381}
3382
3383/* a couple of structures for convenient handling of multiple
3384 * file handles and pipes
3385 */
3386struct file_ref
3387{
3388 int handle;
3389 int flags;
3390};
3391
3392struct pipe_ref
3393{
3394 int rd;
3395 int wr;
3396};
3397
3398/* The following code is derived from the win32 code */
3399
3400static PyObject *
3401_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3402{
3403 struct file_ref stdio[3];
3404 struct pipe_ref p_fd[3];
3405 FILE *p_s[3];
3406 int file_count, i, pipe_err, pipe_pid;
3407 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3408 PyObject *f, *p_f[3];
3409
3410 /* file modes for subsequent fdopen's on pipe handles */
3411 if (mode == O_TEXT)
3412 {
3413 rd_mode = "rt";
3414 wr_mode = "wt";
3415 }
3416 else
3417 {
3418 rd_mode = "rb";
3419 wr_mode = "wb";
3420 }
3421
3422 /* prepare shell references */
3423 if ((shell = getenv("EMXSHELL")) == NULL)
3424 if ((shell = getenv("COMSPEC")) == NULL)
3425 {
3426 errno = ENOENT;
3427 return posix_error();
3428 }
3429
3430 sh_name = _getname(shell);
3431 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3432 opt = "/c";
3433 else
3434 opt = "-c";
3435
3436 /* save current stdio fds + their flags, and set not inheritable */
3437 i = pipe_err = 0;
3438 while (pipe_err >= 0 && i < 3)
3439 {
3440 pipe_err = stdio[i].handle = dup(i);
3441 stdio[i].flags = fcntl(i, F_GETFD, 0);
3442 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3443 i++;
3444 }
3445 if (pipe_err < 0)
3446 {
3447 /* didn't get them all saved - clean up and bail out */
3448 int saved_err = errno;
3449 while (i-- > 0)
3450 {
3451 close(stdio[i].handle);
3452 }
3453 errno = saved_err;
3454 return posix_error();
3455 }
3456
3457 /* create pipe ends */
3458 file_count = 2;
3459 if (n == POPEN_3)
3460 file_count = 3;
3461 i = pipe_err = 0;
3462 while ((pipe_err == 0) && (i < file_count))
3463 pipe_err = pipe((int *)&p_fd[i++]);
3464 if (pipe_err < 0)
3465 {
3466 /* didn't get them all made - clean up and bail out */
3467 while (i-- > 0)
3468 {
3469 close(p_fd[i].wr);
3470 close(p_fd[i].rd);
3471 }
3472 errno = EPIPE;
3473 return posix_error();
3474 }
3475
3476 /* change the actual standard IO streams over temporarily,
3477 * making the retained pipe ends non-inheritable
3478 */
3479 pipe_err = 0;
3480
3481 /* - stdin */
3482 if (dup2(p_fd[0].rd, 0) == 0)
3483 {
3484 close(p_fd[0].rd);
3485 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3486 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3487 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3488 {
3489 close(p_fd[0].wr);
3490 pipe_err = -1;
3491 }
3492 }
3493 else
3494 {
3495 pipe_err = -1;
3496 }
3497
3498 /* - stdout */
3499 if (pipe_err == 0)
3500 {
3501 if (dup2(p_fd[1].wr, 1) == 1)
3502 {
3503 close(p_fd[1].wr);
3504 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3505 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3506 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3507 {
3508 close(p_fd[1].rd);
3509 pipe_err = -1;
3510 }
3511 }
3512 else
3513 {
3514 pipe_err = -1;
3515 }
3516 }
3517
3518 /* - stderr, as required */
3519 if (pipe_err == 0)
3520 switch (n)
3521 {
3522 case POPEN_3:
3523 {
3524 if (dup2(p_fd[2].wr, 2) == 2)
3525 {
3526 close(p_fd[2].wr);
3527 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3528 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3529 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3530 {
3531 close(p_fd[2].rd);
3532 pipe_err = -1;
3533 }
3534 }
3535 else
3536 {
3537 pipe_err = -1;
3538 }
3539 break;
3540 }
3541
3542 case POPEN_4:
3543 {
3544 if (dup2(1, 2) != 2)
3545 {
3546 pipe_err = -1;
3547 }
3548 break;
3549 }
3550 }
3551
3552 /* spawn the child process */
3553 if (pipe_err == 0)
3554 {
3555 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3556 if (pipe_pid == -1)
3557 {
3558 pipe_err = -1;
3559 }
3560 else
3561 {
3562 /* save the PID into the FILE structure
3563 * NOTE: this implementation doesn't actually
3564 * take advantage of this, but do it for
3565 * completeness - AIM Apr01
3566 */
3567 for (i = 0; i < file_count; i++)
3568 p_s[i]->_pid = pipe_pid;
3569 }
3570 }
3571
3572 /* reset standard IO to normal */
3573 for (i = 0; i < 3; i++)
3574 {
3575 dup2(stdio[i].handle, i);
3576 fcntl(i, F_SETFD, stdio[i].flags);
3577 close(stdio[i].handle);
3578 }
3579
3580 /* if any remnant problems, clean up and bail out */
3581 if (pipe_err < 0)
3582 {
3583 for (i = 0; i < 3; i++)
3584 {
3585 close(p_fd[i].rd);
3586 close(p_fd[i].wr);
3587 }
3588 errno = EPIPE;
3589 return posix_error_with_filename(cmdstring);
3590 }
3591
3592 /* build tuple of file objects to return */
3593 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3594 PyFile_SetBufSize(p_f[0], bufsize);
3595 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3596 PyFile_SetBufSize(p_f[1], bufsize);
3597 if (n == POPEN_3)
3598 {
3599 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3600 PyFile_SetBufSize(p_f[0], bufsize);
3601 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3602 }
3603 else
3604 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3605
3606 /*
3607 * Insert the files we've created into the process dictionary
3608 * all referencing the list with the process handle and the
3609 * initial number of files (see description below in _PyPclose).
3610 * Since if _PyPclose later tried to wait on a process when all
3611 * handles weren't closed, it could create a deadlock with the
3612 * child, we spend some energy here to try to ensure that we
3613 * either insert all file handles into the dictionary or none
3614 * at all. It's a little clumsy with the various popen modes
3615 * and variable number of files involved.
3616 */
3617 if (!_PyPopenProcs)
3618 {
3619 _PyPopenProcs = PyDict_New();
3620 }
3621
3622 if (_PyPopenProcs)
3623 {
3624 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3625 int ins_rc[3];
3626
3627 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3628 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3629
3630 procObj = PyList_New(2);
3631 pidObj = PyInt_FromLong((long) pipe_pid);
3632 intObj = PyInt_FromLong((long) file_count);
3633
3634 if (procObj && pidObj && intObj)
3635 {
3636 PyList_SetItem(procObj, 0, pidObj);
3637 PyList_SetItem(procObj, 1, intObj);
3638
3639 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3640 if (fileObj[0])
3641 {
3642 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3643 fileObj[0],
3644 procObj);
3645 }
3646 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3647 if (fileObj[1])
3648 {
3649 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3650 fileObj[1],
3651 procObj);
3652 }
3653 if (file_count >= 3)
3654 {
3655 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3656 if (fileObj[2])
3657 {
3658 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3659 fileObj[2],
3660 procObj);
3661 }
3662 }
3663
3664 if (ins_rc[0] < 0 || !fileObj[0] ||
3665 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3666 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3667 {
3668 /* Something failed - remove any dictionary
3669 * entries that did make it.
3670 */
3671 if (!ins_rc[0] && fileObj[0])
3672 {
3673 PyDict_DelItem(_PyPopenProcs,
3674 fileObj[0]);
3675 }
3676 if (!ins_rc[1] && fileObj[1])
3677 {
3678 PyDict_DelItem(_PyPopenProcs,
3679 fileObj[1]);
3680 }
3681 if (!ins_rc[2] && fileObj[2])
3682 {
3683 PyDict_DelItem(_PyPopenProcs,
3684 fileObj[2]);
3685 }
3686 }
3687 }
3688
3689 /*
3690 * Clean up our localized references for the dictionary keys
3691 * and value since PyDict_SetItem will Py_INCREF any copies
3692 * that got placed in the dictionary.
3693 */
3694 Py_XDECREF(procObj);
3695 Py_XDECREF(fileObj[0]);
3696 Py_XDECREF(fileObj[1]);
3697 Py_XDECREF(fileObj[2]);
3698 }
3699
3700 /* Child is launched. */
3701 return f;
3702}
3703
3704/*
3705 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3706 * exit code for the child process and return as a result of the close.
3707 *
3708 * This function uses the _PyPopenProcs dictionary in order to map the
3709 * input file pointer to information about the process that was
3710 * originally created by the popen* call that created the file pointer.
3711 * The dictionary uses the file pointer as a key (with one entry
3712 * inserted for each file returned by the original popen* call) and a
3713 * single list object as the value for all files from a single call.
3714 * The list object contains the Win32 process handle at [0], and a file
3715 * count at [1], which is initialized to the total number of file
3716 * handles using that list.
3717 *
3718 * This function closes whichever handle it is passed, and decrements
3719 * the file count in the dictionary for the process handle pointed to
3720 * by this file. On the last close (when the file count reaches zero),
3721 * this function will wait for the child process and then return its
3722 * exit code as the result of the close() operation. This permits the
3723 * files to be closed in any order - it is always the close() of the
3724 * final handle that will return the exit code.
3725 */
3726
3727 /* RED_FLAG 31-Aug-2000 Tim
3728 * This is always called (today!) between a pair of
3729 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3730 * macros. So the thread running this has no valid thread state, as
3731 * far as Python is concerned. However, this calls some Python API
3732 * functions that cannot be called safely without a valid thread
3733 * state, in particular PyDict_GetItem.
3734 * As a temporary hack (although it may last for years ...), we
3735 * *rely* on not having a valid thread state in this function, in
3736 * order to create our own "from scratch".
3737 * This will deadlock if _PyPclose is ever called by a thread
3738 * holding the global lock.
3739 * (The OS/2 EMX thread support appears to cover the case where the
3740 * lock is already held - AIM Apr01)
3741 */
3742
3743static int _PyPclose(FILE *file)
3744{
3745 int result;
3746 int exit_code;
3747 int pipe_pid;
3748 PyObject *procObj, *pidObj, *intObj, *fileObj;
3749 int file_count;
3750#ifdef WITH_THREAD
3751 PyInterpreterState* pInterpreterState;
3752 PyThreadState* pThreadState;
3753#endif
3754
3755 /* Close the file handle first, to ensure it can't block the
3756 * child from exiting if it's the last handle.
3757 */
3758 result = fclose(file);
3759
3760#ifdef WITH_THREAD
3761 /* Bootstrap a valid thread state into existence. */
3762 pInterpreterState = PyInterpreterState_New();
3763 if (!pInterpreterState) {
3764 /* Well, we're hosed now! We don't have a thread
3765 * state, so can't call a nice error routine, or raise
3766 * an exception. Just die.
3767 */
3768 Py_FatalError("unable to allocate interpreter state "
3769 "when closing popen object.");
3770 return -1; /* unreachable */
3771 }
3772 pThreadState = PyThreadState_New(pInterpreterState);
3773 if (!pThreadState) {
3774 Py_FatalError("unable to allocate thread state "
3775 "when closing popen object.");
3776 return -1; /* unreachable */
3777 }
3778 /* Grab the global lock. Note that this will deadlock if the
3779 * current thread already has the lock! (see RED_FLAG comments
3780 * before this function)
3781 */
3782 PyEval_RestoreThread(pThreadState);
3783#endif
3784
3785 if (_PyPopenProcs)
3786 {
3787 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3788 (procObj = PyDict_GetItem(_PyPopenProcs,
3789 fileObj)) != NULL &&
3790 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3791 (intObj = PyList_GetItem(procObj,1)) != NULL)
3792 {
3793 pipe_pid = (int) PyInt_AsLong(pidObj);
3794 file_count = (int) PyInt_AsLong(intObj);
3795
3796 if (file_count > 1)
3797 {
3798 /* Still other files referencing process */
3799 file_count--;
3800 PyList_SetItem(procObj,1,
3801 PyInt_FromLong((long) file_count));
3802 }
3803 else
3804 {
3805 /* Last file for this process */
3806 if (result != EOF &&
3807 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3808 {
3809 /* extract exit status */
3810 if (WIFEXITED(exit_code))
3811 {
3812 result = WEXITSTATUS(exit_code);
3813 }
3814 else
3815 {
3816 errno = EPIPE;
3817 result = -1;
3818 }
3819 }
3820 else
3821 {
3822 /* Indicate failure - this will cause the file object
3823 * to raise an I/O error and translate the last
3824 * error code from errno. We do have a problem with
3825 * last errors that overlap the normal errno table,
3826 * but that's a consistent problem with the file object.
3827 */
3828 result = -1;
3829 }
3830 }
3831
3832 /* Remove this file pointer from dictionary */
3833 PyDict_DelItem(_PyPopenProcs, fileObj);
3834
3835 if (PyDict_Size(_PyPopenProcs) == 0)
3836 {
3837 Py_DECREF(_PyPopenProcs);
3838 _PyPopenProcs = NULL;
3839 }
3840
3841 } /* if object retrieval ok */
3842
3843 Py_XDECREF(fileObj);
3844 } /* if _PyPopenProcs */
3845
3846#ifdef WITH_THREAD
3847 /* Tear down the thread & interpreter states.
3848 * Note that interpreter state clear & delete functions automatically
3849 * call the thread clear & delete functions, and indeed insist on
3850 * doing that themselves. The lock must be held during the clear, but
3851 * need not be held during the delete.
3852 */
3853 PyInterpreterState_Clear(pInterpreterState);
3854 PyEval_ReleaseThread(pThreadState);
3855 PyInterpreterState_Delete(pInterpreterState);
3856#endif
3857
3858 return result;
3859}
3860
3861#endif /* PYCC_??? */
3862
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003863#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003864
3865/*
3866 * Portable 'popen' replacement for Win32.
3867 *
3868 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3869 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003870 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003871 */
3872
3873#include <malloc.h>
3874#include <io.h>
3875#include <fcntl.h>
3876
3877/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3878#define POPEN_1 1
3879#define POPEN_2 2
3880#define POPEN_3 3
3881#define POPEN_4 4
3882
3883static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003884static int _PyPclose(FILE *file);
3885
3886/*
3887 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003888 * for use when retrieving the process exit code. See _PyPclose() below
3889 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003890 */
3891static PyObject *_PyPopenProcs = NULL;
3892
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003893
3894/* popen that works from a GUI.
3895 *
3896 * The result of this function is a pipe (file) connected to the
3897 * processes stdin or stdout, depending on the requested mode.
3898 */
3899
3900static PyObject *
3901posix_popen(PyObject *self, PyObject *args)
3902{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003903 PyObject *f, *s;
3904 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003905
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003906 char *cmdstring;
3907 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003908 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003909 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003910 return NULL;
3911
3912 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003913
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003914 if (*mode == 'r')
3915 tm = _O_RDONLY;
3916 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003917 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003918 return NULL;
3919 } else
3920 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003921
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003922 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003923 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003924 return NULL;
3925 }
3926
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003927 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003928 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003929 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003930 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003931 else
3932 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3933
3934 return f;
3935}
3936
3937/* Variation on win32pipe.popen
3938 *
3939 * The result of this function is a pipe (file) connected to the
3940 * process's stdin, and a pipe connected to the process's stdout.
3941 */
3942
3943static PyObject *
3944win32_popen2(PyObject *self, PyObject *args)
3945{
3946 PyObject *f;
3947 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003948
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003949 char *cmdstring;
3950 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003951 int bufsize = -1;
3952 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003953 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003954
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003955 if (*mode == 't')
3956 tm = _O_TEXT;
3957 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003958 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003959 return NULL;
3960 } else
3961 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003962
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003963 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003964 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003965 return NULL;
3966 }
3967
3968 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003969
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003970 return f;
3971}
3972
3973/*
3974 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003975 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003976 * The result of this function is 3 pipes - the process's stdin,
3977 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 */
3979
3980static PyObject *
3981win32_popen3(PyObject *self, PyObject *args)
3982{
3983 PyObject *f;
3984 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003985
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 char *cmdstring;
3987 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003988 int bufsize = -1;
3989 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003990 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003991
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003992 if (*mode == 't')
3993 tm = _O_TEXT;
3994 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003995 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003996 return NULL;
3997 } else
3998 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003999
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004000 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004001 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004002 return NULL;
4003 }
4004
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004005 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004006
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004007 return f;
4008}
4009
4010/*
4011 * Variation on win32pipe.popen
4012 *
Tim Peters5aa91602002-01-30 05:46:57 +00004013 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004014 * and stdout+stderr combined as a single pipe.
4015 */
4016
4017static PyObject *
4018win32_popen4(PyObject *self, PyObject *args)
4019{
4020 PyObject *f;
4021 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004022
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004023 char *cmdstring;
4024 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004025 int bufsize = -1;
4026 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004027 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004028
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004029 if (*mode == 't')
4030 tm = _O_TEXT;
4031 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004032 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004033 return NULL;
4034 } else
4035 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004036
4037 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004038 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004039 return NULL;
4040 }
4041
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004042 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004043
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004044 return f;
4045}
4046
Mark Hammond08501372001-01-31 07:30:29 +00004047static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004048_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004049 HANDLE hStdin,
4050 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004051 HANDLE hStderr,
4052 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004053{
4054 PROCESS_INFORMATION piProcInfo;
4055 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004056 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004057 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004058 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004059 int i;
4060 int x;
4061
4062 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004063 char *comshell;
4064
Tim Peters92e4dd82002-10-05 01:47:34 +00004065 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004066 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4067 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004068
4069 /* Explicitly check if we are using COMMAND.COM. If we are
4070 * then use the w9xpopen hack.
4071 */
4072 comshell = s1 + x;
4073 while (comshell >= s1 && *comshell != '\\')
4074 --comshell;
4075 ++comshell;
4076
4077 if (GetVersion() < 0x80000000 &&
4078 _stricmp(comshell, "command.com") != 0) {
4079 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004080 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004081 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004082 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004083 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004084 }
4085 else {
4086 /*
Tim Peters402d5982001-08-27 06:37:48 +00004087 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4088 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004089 */
Mark Hammond08501372001-01-31 07:30:29 +00004090 char modulepath[_MAX_PATH];
4091 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004092 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4093 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004094 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004095 x = i+1;
4096 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004097 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004098 strncat(modulepath,
4099 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004100 (sizeof(modulepath)/sizeof(modulepath[0]))
4101 -strlen(modulepath));
4102 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004103 /* Eeek - file-not-found - possibly an embedding
4104 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004105 */
Tim Peters5aa91602002-01-30 05:46:57 +00004106 strncpy(modulepath,
4107 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004108 sizeof(modulepath)/sizeof(modulepath[0]));
4109 if (modulepath[strlen(modulepath)-1] != '\\')
4110 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004111 strncat(modulepath,
4112 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004113 (sizeof(modulepath)/sizeof(modulepath[0]))
4114 -strlen(modulepath));
4115 /* No where else to look - raise an easily identifiable
4116 error, rather than leaving Windows to report
4117 "file not found" - as the user is probably blissfully
4118 unaware this shim EXE is used, and it will confuse them.
4119 (well, it confused me for a while ;-)
4120 */
4121 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004122 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004123 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004124 "for popen to work with your shell "
4125 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004126 szConsoleSpawn);
4127 return FALSE;
4128 }
4129 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004130 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004131 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004132 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004133
Tim Peters92e4dd82002-10-05 01:47:34 +00004134 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004135 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004136 /* To maintain correct argument passing semantics,
4137 we pass the command-line as it stands, and allow
4138 quoting to be applied. w9xpopen.exe will then
4139 use its argv vector, and re-quote the necessary
4140 args for the ultimate child process.
4141 */
Tim Peters75cdad52001-11-28 22:07:30 +00004142 PyOS_snprintf(
4143 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004144 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004145 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004146 s1,
4147 s3,
4148 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004149 /* Not passing CREATE_NEW_CONSOLE has been known to
4150 cause random failures on win9x. Specifically a
4151 dialog:
4152 "Your program accessed mem currently in use at xxx"
4153 and a hopeful warning about the stability of your
4154 system.
4155 Cost is Ctrl+C wont kill children, but anyone
4156 who cares can have a go!
4157 */
4158 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 }
4160 }
4161
4162 /* Could be an else here to try cmd.exe / command.com in the path
4163 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004164 else {
Tim Peters402d5982001-08-27 06:37:48 +00004165 PyErr_SetString(PyExc_RuntimeError,
4166 "Cannot locate a COMSPEC environment variable to "
4167 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004168 return FALSE;
4169 }
Tim Peters5aa91602002-01-30 05:46:57 +00004170
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004171 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4172 siStartInfo.cb = sizeof(STARTUPINFO);
4173 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4174 siStartInfo.hStdInput = hStdin;
4175 siStartInfo.hStdOutput = hStdout;
4176 siStartInfo.hStdError = hStderr;
4177 siStartInfo.wShowWindow = SW_HIDE;
4178
4179 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004180 s2,
4181 NULL,
4182 NULL,
4183 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004184 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004185 NULL,
4186 NULL,
4187 &siStartInfo,
4188 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004189 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004190 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004191
Mark Hammondb37a3732000-08-14 04:47:33 +00004192 /* Return process handle */
4193 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004194 return TRUE;
4195 }
Tim Peters402d5982001-08-27 06:37:48 +00004196 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004197 return FALSE;
4198}
4199
4200/* The following code is based off of KB: Q190351 */
4201
4202static PyObject *
4203_PyPopen(char *cmdstring, int mode, int n)
4204{
4205 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4206 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004207 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004208
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 SECURITY_ATTRIBUTES saAttr;
4210 BOOL fSuccess;
4211 int fd1, fd2, fd3;
4212 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004213 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004214 PyObject *f;
4215
4216 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4217 saAttr.bInheritHandle = TRUE;
4218 saAttr.lpSecurityDescriptor = NULL;
4219
4220 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4221 return win32_error("CreatePipe", NULL);
4222
4223 /* Create new output read handle and the input write handle. Set
4224 * the inheritance properties to FALSE. Otherwise, the child inherits
4225 * the these handles; resulting in non-closeable handles to the pipes
4226 * being created. */
4227 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004228 GetCurrentProcess(), &hChildStdinWrDup, 0,
4229 FALSE,
4230 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 if (!fSuccess)
4232 return win32_error("DuplicateHandle", NULL);
4233
4234 /* Close the inheritable version of ChildStdin
4235 that we're using. */
4236 CloseHandle(hChildStdinWr);
4237
4238 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4239 return win32_error("CreatePipe", NULL);
4240
4241 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004242 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4243 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004244 if (!fSuccess)
4245 return win32_error("DuplicateHandle", NULL);
4246
4247 /* Close the inheritable version of ChildStdout
4248 that we're using. */
4249 CloseHandle(hChildStdoutRd);
4250
4251 if (n != POPEN_4) {
4252 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4253 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004254 fSuccess = DuplicateHandle(GetCurrentProcess(),
4255 hChildStderrRd,
4256 GetCurrentProcess(),
4257 &hChildStderrRdDup, 0,
4258 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004259 if (!fSuccess)
4260 return win32_error("DuplicateHandle", NULL);
4261 /* Close the inheritable version of ChildStdErr that we're using. */
4262 CloseHandle(hChildStderrRd);
4263 }
Tim Peters5aa91602002-01-30 05:46:57 +00004264
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004265 switch (n) {
4266 case POPEN_1:
4267 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4268 case _O_WRONLY | _O_TEXT:
4269 /* Case for writing to child Stdin in text mode. */
4270 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4271 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004272 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004273 PyFile_SetBufSize(f, 0);
4274 /* We don't care about these pipes anymore, so close them. */
4275 CloseHandle(hChildStdoutRdDup);
4276 CloseHandle(hChildStderrRdDup);
4277 break;
4278
4279 case _O_RDONLY | _O_TEXT:
4280 /* Case for reading from child Stdout in text mode. */
4281 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4282 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004283 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004284 PyFile_SetBufSize(f, 0);
4285 /* We don't care about these pipes anymore, so close them. */
4286 CloseHandle(hChildStdinWrDup);
4287 CloseHandle(hChildStderrRdDup);
4288 break;
4289
4290 case _O_RDONLY | _O_BINARY:
4291 /* Case for readinig from child Stdout in binary mode. */
4292 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4293 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004294 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004295 PyFile_SetBufSize(f, 0);
4296 /* We don't care about these pipes anymore, so close them. */
4297 CloseHandle(hChildStdinWrDup);
4298 CloseHandle(hChildStderrRdDup);
4299 break;
4300
4301 case _O_WRONLY | _O_BINARY:
4302 /* Case for writing to child Stdin in binary mode. */
4303 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4304 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004305 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004306 PyFile_SetBufSize(f, 0);
4307 /* We don't care about these pipes anymore, so close them. */
4308 CloseHandle(hChildStdoutRdDup);
4309 CloseHandle(hChildStderrRdDup);
4310 break;
4311 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004312 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004313 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004314
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004315 case POPEN_2:
4316 case POPEN_4:
4317 {
4318 char *m1, *m2;
4319 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004320
Tim Peters7dca21e2002-08-19 00:42:29 +00004321 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004322 m1 = "r";
4323 m2 = "w";
4324 } else {
4325 m1 = "rb";
4326 m2 = "wb";
4327 }
4328
4329 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4330 f1 = _fdopen(fd1, m2);
4331 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4332 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004333 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004334 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004335 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004336 PyFile_SetBufSize(p2, 0);
4337
4338 if (n != 4)
4339 CloseHandle(hChildStderrRdDup);
4340
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004341 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004342 Py_XDECREF(p1);
4343 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004344 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004345 break;
4346 }
Tim Peters5aa91602002-01-30 05:46:57 +00004347
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004348 case POPEN_3:
4349 {
4350 char *m1, *m2;
4351 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004352
Tim Peters7dca21e2002-08-19 00:42:29 +00004353 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354 m1 = "r";
4355 m2 = "w";
4356 } else {
4357 m1 = "rb";
4358 m2 = "wb";
4359 }
4360
4361 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4362 f1 = _fdopen(fd1, m2);
4363 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4364 f2 = _fdopen(fd2, m1);
4365 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4366 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004367 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004368 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4369 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004370 PyFile_SetBufSize(p1, 0);
4371 PyFile_SetBufSize(p2, 0);
4372 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004373 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004374 Py_XDECREF(p1);
4375 Py_XDECREF(p2);
4376 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004377 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004378 break;
4379 }
4380 }
4381
4382 if (n == POPEN_4) {
4383 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004384 hChildStdinRd,
4385 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004386 hChildStdoutWr,
4387 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004388 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004389 }
4390 else {
4391 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004392 hChildStdinRd,
4393 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004394 hChildStderrWr,
4395 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004396 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004397 }
4398
Mark Hammondb37a3732000-08-14 04:47:33 +00004399 /*
4400 * Insert the files we've created into the process dictionary
4401 * all referencing the list with the process handle and the
4402 * initial number of files (see description below in _PyPclose).
4403 * Since if _PyPclose later tried to wait on a process when all
4404 * handles weren't closed, it could create a deadlock with the
4405 * child, we spend some energy here to try to ensure that we
4406 * either insert all file handles into the dictionary or none
4407 * at all. It's a little clumsy with the various popen modes
4408 * and variable number of files involved.
4409 */
4410 if (!_PyPopenProcs) {
4411 _PyPopenProcs = PyDict_New();
4412 }
4413
4414 if (_PyPopenProcs) {
4415 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4416 int ins_rc[3];
4417
4418 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4419 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4420
4421 procObj = PyList_New(2);
4422 hProcessObj = PyLong_FromVoidPtr(hProcess);
4423 intObj = PyInt_FromLong(file_count);
4424
4425 if (procObj && hProcessObj && intObj) {
4426 PyList_SetItem(procObj,0,hProcessObj);
4427 PyList_SetItem(procObj,1,intObj);
4428
4429 fileObj[0] = PyLong_FromVoidPtr(f1);
4430 if (fileObj[0]) {
4431 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4432 fileObj[0],
4433 procObj);
4434 }
4435 if (file_count >= 2) {
4436 fileObj[1] = PyLong_FromVoidPtr(f2);
4437 if (fileObj[1]) {
4438 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4439 fileObj[1],
4440 procObj);
4441 }
4442 }
4443 if (file_count >= 3) {
4444 fileObj[2] = PyLong_FromVoidPtr(f3);
4445 if (fileObj[2]) {
4446 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4447 fileObj[2],
4448 procObj);
4449 }
4450 }
4451
4452 if (ins_rc[0] < 0 || !fileObj[0] ||
4453 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4454 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4455 /* Something failed - remove any dictionary
4456 * entries that did make it.
4457 */
4458 if (!ins_rc[0] && fileObj[0]) {
4459 PyDict_DelItem(_PyPopenProcs,
4460 fileObj[0]);
4461 }
4462 if (!ins_rc[1] && fileObj[1]) {
4463 PyDict_DelItem(_PyPopenProcs,
4464 fileObj[1]);
4465 }
4466 if (!ins_rc[2] && fileObj[2]) {
4467 PyDict_DelItem(_PyPopenProcs,
4468 fileObj[2]);
4469 }
4470 }
4471 }
Tim Peters5aa91602002-01-30 05:46:57 +00004472
Mark Hammondb37a3732000-08-14 04:47:33 +00004473 /*
4474 * Clean up our localized references for the dictionary keys
4475 * and value since PyDict_SetItem will Py_INCREF any copies
4476 * that got placed in the dictionary.
4477 */
4478 Py_XDECREF(procObj);
4479 Py_XDECREF(fileObj[0]);
4480 Py_XDECREF(fileObj[1]);
4481 Py_XDECREF(fileObj[2]);
4482 }
4483
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 /* Child is launched. Close the parents copy of those pipe
4485 * handles that only the child should have open. You need to
4486 * make sure that no handles to the write end of the output pipe
4487 * are maintained in this process or else the pipe will not close
4488 * when the child process exits and the ReadFile will hang. */
4489
4490 if (!CloseHandle(hChildStdinRd))
4491 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004492
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004493 if (!CloseHandle(hChildStdoutWr))
4494 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004495
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004496 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4497 return win32_error("CloseHandle", NULL);
4498
4499 return f;
4500}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004501
4502/*
4503 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4504 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004505 *
4506 * This function uses the _PyPopenProcs dictionary in order to map the
4507 * input file pointer to information about the process that was
4508 * originally created by the popen* call that created the file pointer.
4509 * The dictionary uses the file pointer as a key (with one entry
4510 * inserted for each file returned by the original popen* call) and a
4511 * single list object as the value for all files from a single call.
4512 * The list object contains the Win32 process handle at [0], and a file
4513 * count at [1], which is initialized to the total number of file
4514 * handles using that list.
4515 *
4516 * This function closes whichever handle it is passed, and decrements
4517 * the file count in the dictionary for the process handle pointed to
4518 * by this file. On the last close (when the file count reaches zero),
4519 * this function will wait for the child process and then return its
4520 * exit code as the result of the close() operation. This permits the
4521 * files to be closed in any order - it is always the close() of the
4522 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004523 */
Tim Peters736aa322000-09-01 06:51:24 +00004524
4525 /* RED_FLAG 31-Aug-2000 Tim
4526 * This is always called (today!) between a pair of
4527 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4528 * macros. So the thread running this has no valid thread state, as
4529 * far as Python is concerned. However, this calls some Python API
4530 * functions that cannot be called safely without a valid thread
4531 * state, in particular PyDict_GetItem.
4532 * As a temporary hack (although it may last for years ...), we
4533 * *rely* on not having a valid thread state in this function, in
4534 * order to create our own "from scratch".
4535 * This will deadlock if _PyPclose is ever called by a thread
4536 * holding the global lock.
4537 */
4538
Fredrik Lundh56055a42000-07-23 19:47:12 +00004539static int _PyPclose(FILE *file)
4540{
Fredrik Lundh20318932000-07-26 17:29:12 +00004541 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004542 DWORD exit_code;
4543 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004544 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4545 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004546#ifdef WITH_THREAD
4547 PyInterpreterState* pInterpreterState;
4548 PyThreadState* pThreadState;
4549#endif
4550
Fredrik Lundh20318932000-07-26 17:29:12 +00004551 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004552 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004553 */
4554 result = fclose(file);
4555
Tim Peters736aa322000-09-01 06:51:24 +00004556#ifdef WITH_THREAD
4557 /* Bootstrap a valid thread state into existence. */
4558 pInterpreterState = PyInterpreterState_New();
4559 if (!pInterpreterState) {
4560 /* Well, we're hosed now! We don't have a thread
4561 * state, so can't call a nice error routine, or raise
4562 * an exception. Just die.
4563 */
4564 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004565 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004566 return -1; /* unreachable */
4567 }
4568 pThreadState = PyThreadState_New(pInterpreterState);
4569 if (!pThreadState) {
4570 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004571 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004572 return -1; /* unreachable */
4573 }
4574 /* Grab the global lock. Note that this will deadlock if the
4575 * current thread already has the lock! (see RED_FLAG comments
4576 * before this function)
4577 */
4578 PyEval_RestoreThread(pThreadState);
4579#endif
4580
Fredrik Lundh56055a42000-07-23 19:47:12 +00004581 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004582 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4583 (procObj = PyDict_GetItem(_PyPopenProcs,
4584 fileObj)) != NULL &&
4585 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4586 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4587
4588 hProcess = PyLong_AsVoidPtr(hProcessObj);
4589 file_count = PyInt_AsLong(intObj);
4590
4591 if (file_count > 1) {
4592 /* Still other files referencing process */
4593 file_count--;
4594 PyList_SetItem(procObj,1,
4595 PyInt_FromLong(file_count));
4596 } else {
4597 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004598 if (result != EOF &&
4599 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4600 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004601 /* Possible truncation here in 16-bit environments, but
4602 * real exit codes are just the lower byte in any event.
4603 */
4604 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004605 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004606 /* Indicate failure - this will cause the file object
4607 * to raise an I/O error and translate the last Win32
4608 * error code from errno. We do have a problem with
4609 * last errors that overlap the normal errno table,
4610 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004611 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004612 if (result != EOF) {
4613 /* If the error wasn't from the fclose(), then
4614 * set errno for the file object error handling.
4615 */
4616 errno = GetLastError();
4617 }
4618 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004619 }
4620
4621 /* Free up the native handle at this point */
4622 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004623 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004624
Mark Hammondb37a3732000-08-14 04:47:33 +00004625 /* Remove this file pointer from dictionary */
4626 PyDict_DelItem(_PyPopenProcs, fileObj);
4627
4628 if (PyDict_Size(_PyPopenProcs) == 0) {
4629 Py_DECREF(_PyPopenProcs);
4630 _PyPopenProcs = NULL;
4631 }
4632
4633 } /* if object retrieval ok */
4634
4635 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004636 } /* if _PyPopenProcs */
4637
Tim Peters736aa322000-09-01 06:51:24 +00004638#ifdef WITH_THREAD
4639 /* Tear down the thread & interpreter states.
4640 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004641 * call the thread clear & delete functions, and indeed insist on
4642 * doing that themselves. The lock must be held during the clear, but
4643 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004644 */
4645 PyInterpreterState_Clear(pInterpreterState);
4646 PyEval_ReleaseThread(pThreadState);
4647 PyInterpreterState_Delete(pInterpreterState);
4648#endif
4649
Fredrik Lundh56055a42000-07-23 19:47:12 +00004650 return result;
4651}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004652
4653#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004655posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004656{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004657 char *name;
4658 char *mode = "r";
4659 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004660 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004661 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004662 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004663 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004664 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004665 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004666 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004667 if (fp == NULL)
4668 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004669 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004670 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004671 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004672 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004673}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004674
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004675#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004676#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004677
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004678
Guido van Rossumb6775db1994-08-01 11:34:53 +00004679#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004681"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682Set the current process's user id.");
4683
Barry Warsaw53699e91996-12-10 23:23:01 +00004684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004685posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004686{
4687 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004688 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004689 return NULL;
4690 if (setuid(uid) < 0)
4691 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004692 Py_INCREF(Py_None);
4693 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004694}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004695#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004697
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004698#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004700"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701Set the current process's effective user id.");
4702
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004703static PyObject *
4704posix_seteuid (PyObject *self, PyObject *args)
4705{
4706 int euid;
4707 if (!PyArg_ParseTuple(args, "i", &euid)) {
4708 return NULL;
4709 } else if (seteuid(euid) < 0) {
4710 return posix_error();
4711 } else {
4712 Py_INCREF(Py_None);
4713 return Py_None;
4714 }
4715}
4716#endif /* HAVE_SETEUID */
4717
4718#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Set the current process's effective group id.");
4722
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004723static PyObject *
4724posix_setegid (PyObject *self, PyObject *args)
4725{
4726 int egid;
4727 if (!PyArg_ParseTuple(args, "i", &egid)) {
4728 return NULL;
4729 } else if (setegid(egid) < 0) {
4730 return posix_error();
4731 } else {
4732 Py_INCREF(Py_None);
4733 return Py_None;
4734 }
4735}
4736#endif /* HAVE_SETEGID */
4737
4738#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004740"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741Set the current process's real and effective user ids.");
4742
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004743static PyObject *
4744posix_setreuid (PyObject *self, PyObject *args)
4745{
4746 int ruid, euid;
4747 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4748 return NULL;
4749 } else if (setreuid(ruid, euid) < 0) {
4750 return posix_error();
4751 } else {
4752 Py_INCREF(Py_None);
4753 return Py_None;
4754 }
4755}
4756#endif /* HAVE_SETREUID */
4757
4758#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004760"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761Set the current process's real and effective group ids.");
4762
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004763static PyObject *
4764posix_setregid (PyObject *self, PyObject *args)
4765{
4766 int rgid, egid;
4767 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4768 return NULL;
4769 } else if (setregid(rgid, egid) < 0) {
4770 return posix_error();
4771 } else {
4772 Py_INCREF(Py_None);
4773 return Py_None;
4774 }
4775}
4776#endif /* HAVE_SETREGID */
4777
Guido van Rossumb6775db1994-08-01 11:34:53 +00004778#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004779PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004780"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004782
Barry Warsaw53699e91996-12-10 23:23:01 +00004783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004784posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004785{
4786 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004787 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004788 return NULL;
4789 if (setgid(gid) < 0)
4790 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004791 Py_INCREF(Py_None);
4792 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004793}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004794#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004795
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004796#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004797PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004798"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004799Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004800
4801static PyObject *
4802posix_setgroups(PyObject *self, PyObject *args)
4803{
4804 PyObject *groups;
4805 int i, len;
4806 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004807
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004808 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4809 return NULL;
4810 if (!PySequence_Check(groups)) {
4811 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4812 return NULL;
4813 }
4814 len = PySequence_Size(groups);
4815 if (len > MAX_GROUPS) {
4816 PyErr_SetString(PyExc_ValueError, "too many groups");
4817 return NULL;
4818 }
4819 for(i = 0; i < len; i++) {
4820 PyObject *elem;
4821 elem = PySequence_GetItem(groups, i);
4822 if (!elem)
4823 return NULL;
4824 if (!PyInt_Check(elem)) {
4825 PyErr_SetString(PyExc_TypeError,
4826 "groups must be integers");
4827 Py_DECREF(elem);
4828 return NULL;
4829 }
4830 /* XXX: check that value fits into gid_t. */
4831 grouplist[i] = PyInt_AsLong(elem);
4832 Py_DECREF(elem);
4833 }
4834
4835 if (setgroups(len, grouplist) < 0)
4836 return posix_error();
4837 Py_INCREF(Py_None);
4838 return Py_None;
4839}
4840#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004841
Guido van Rossumb6775db1994-08-01 11:34:53 +00004842#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004843PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004844"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004845Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004846
Barry Warsaw53699e91996-12-10 23:23:01 +00004847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004848posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004849{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004850 int pid, options;
4851#ifdef UNION_WAIT
4852 union wait status;
4853#define status_i (status.w_status)
4854#else
4855 int status;
4856#define status_i status
4857#endif
4858 status_i = 0;
4859
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004860 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004861 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004862 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004863 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004864 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004865 if (pid == -1)
4866 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004867 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004868 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004869}
4870
Tim Petersab034fa2002-02-01 11:27:43 +00004871#elif defined(HAVE_CWAIT)
4872
4873/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004875"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004877
4878static PyObject *
4879posix_waitpid(PyObject *self, PyObject *args)
4880{
4881 int pid, options;
4882 int status;
4883
4884 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4885 return NULL;
4886 Py_BEGIN_ALLOW_THREADS
4887 pid = _cwait(&status, pid, options);
4888 Py_END_ALLOW_THREADS
4889 if (pid == -1)
4890 return posix_error();
4891 else
4892 /* shift the status left a byte so this is more like the
4893 POSIX waitpid */
4894 return Py_BuildValue("ii", pid, status << 8);
4895}
4896#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004897
Guido van Rossumad0ee831995-03-01 10:34:45 +00004898#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004899PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004900"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004901Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004902
Barry Warsaw53699e91996-12-10 23:23:01 +00004903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004904posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004905{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004906 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004907#ifdef UNION_WAIT
4908 union wait status;
4909#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004910#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004911 int status;
4912#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004913#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004914 if (!PyArg_ParseTuple(args, ":wait"))
4915 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004916 status_i = 0;
4917 Py_BEGIN_ALLOW_THREADS
4918 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004920 if (pid == -1)
4921 return posix_error();
4922 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004923 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004924#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004925}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004926#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004935{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004936#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004937 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004938#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004939#ifdef MS_WINDOWS
4940 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4941#else
4942 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4943#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004944#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004945}
4946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004947
Guido van Rossumb6775db1994-08-01 11:34:53 +00004948#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004949PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004950"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004952
Barry Warsaw53699e91996-12-10 23:23:01 +00004953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004954posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004955{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004956 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004957 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004958 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004960 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004961 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004962 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004963 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004964 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004965 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004966 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004967}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004968#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Guido van Rossumb6775db1994-08-01 11:34:53 +00004971#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004972PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004973"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004975
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004977posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004978{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004979 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004980}
4981#endif /* HAVE_SYMLINK */
4982
4983
4984#ifdef HAVE_TIMES
4985#ifndef HZ
4986#define HZ 60 /* Universal constant :-) */
4987#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004988
Guido van Rossumd48f2521997-12-05 22:19:34 +00004989#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4990static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004991system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004992{
4993 ULONG value = 0;
4994
4995 Py_BEGIN_ALLOW_THREADS
4996 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4997 Py_END_ALLOW_THREADS
4998
4999 return value;
5000}
5001
5002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005003posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005004{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00005006 return NULL;
5007
5008 /* Currently Only Uptime is Provided -- Others Later */
5009 return Py_BuildValue("ddddd",
5010 (double)0 /* t.tms_utime / HZ */,
5011 (double)0 /* t.tms_stime / HZ */,
5012 (double)0 /* t.tms_cutime / HZ */,
5013 (double)0 /* t.tms_cstime / HZ */,
5014 (double)system_uptime() / 1000);
5015}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005016#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005018posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005019{
5020 struct tms t;
5021 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005022 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00005023 return NULL;
5024 errno = 0;
5025 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005026 if (c == (clock_t) -1)
5027 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005028 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005029 (double)t.tms_utime / HZ,
5030 (double)t.tms_stime / HZ,
5031 (double)t.tms_cutime / HZ,
5032 (double)t.tms_cstime / HZ,
5033 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005034}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005035#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005036#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005037
5038
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005039#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005040#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005042posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005043{
5044 FILETIME create, exit, kernel, user;
5045 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005046 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005047 return NULL;
5048 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005049 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5050 /* The fields of a FILETIME structure are the hi and lo part
5051 of a 64-bit value expressed in 100 nanosecond units.
5052 1e7 is one second in such units; 1e-7 the inverse.
5053 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5054 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005055 return Py_BuildValue(
5056 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005057 (double)(kernel.dwHighDateTime*429.4967296 +
5058 kernel.dwLowDateTime*1e-7),
5059 (double)(user.dwHighDateTime*429.4967296 +
5060 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005061 (double)0,
5062 (double)0,
5063 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005064}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005065#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005066
5067#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005069"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005070Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005071#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005072
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005073
Guido van Rossumb6775db1994-08-01 11:34:53 +00005074#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Barry Warsaw53699e91996-12-10 23:23:01 +00005079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005080posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005081{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005082 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005083 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005084 if (setsid() < 0)
5085 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005086 Py_INCREF(Py_None);
5087 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005088}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005089#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005090
Guido van Rossumb6775db1994-08-01 11:34:53 +00005091#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005092PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005093"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005094Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005095
Barry Warsaw53699e91996-12-10 23:23:01 +00005096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005097posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005098{
5099 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005100 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005101 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005102 if (setpgid(pid, pgrp) < 0)
5103 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005104 Py_INCREF(Py_None);
5105 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005106}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005107#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005109
Guido van Rossumb6775db1994-08-01 11:34:53 +00005110#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005111PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005112"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005113Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005114
Barry Warsaw53699e91996-12-10 23:23:01 +00005115static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005116posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005117{
5118 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005119 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005120 return NULL;
5121 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005122 if (pgid < 0)
5123 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005124 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005125}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005126#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005128
Guido van Rossumb6775db1994-08-01 11:34:53 +00005129#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005131"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005132Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005133
Barry Warsaw53699e91996-12-10 23:23:01 +00005134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005136{
5137 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005138 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005139 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005140 if (tcsetpgrp(fd, pgid) < 0)
5141 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005142 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005143 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005144}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005145#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005146
Guido van Rossum687dd131993-05-17 08:34:16 +00005147/* Functions acting on file descriptors */
5148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005150"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005151Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005152
Barry Warsaw53699e91996-12-10 23:23:01 +00005153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005154posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005155{
Mark Hammondef8b6542001-05-13 08:04:26 +00005156 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005157 int flag;
5158 int mode = 0777;
5159 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005160
5161#ifdef MS_WINDOWS
5162 if (unicode_file_names()) {
5163 PyUnicodeObject *po;
5164 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5165 Py_BEGIN_ALLOW_THREADS
5166 /* PyUnicode_AS_UNICODE OK without thread
5167 lock as it is a simple dereference. */
5168 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5169 Py_END_ALLOW_THREADS
5170 if (fd < 0)
5171 return posix_error();
5172 return PyInt_FromLong((long)fd);
5173 }
5174 /* Drop the argument parsing error as narrow strings
5175 are also valid. */
5176 PyErr_Clear();
5177 }
5178#endif
5179
Tim Peters5aa91602002-01-30 05:46:57 +00005180 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005181 Py_FileSystemDefaultEncoding, &file,
5182 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005183 return NULL;
5184
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005186 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005188 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005189 return posix_error_with_allocated_filename(file);
5190 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005191 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005192}
5193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005195PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005196"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005198
Barry Warsaw53699e91996-12-10 23:23:01 +00005199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005200posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005201{
5202 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005203 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005204 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005205 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005206 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005207 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005208 if (res < 0)
5209 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005210 Py_INCREF(Py_None);
5211 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005212}
5213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005215PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005216"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005217Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005218
Barry Warsaw53699e91996-12-10 23:23:01 +00005219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005220posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005221{
5222 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005223 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005224 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005225 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005226 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005227 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005228 if (fd < 0)
5229 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005230 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005231}
5232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005234PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005235"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005236Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005237
Barry Warsaw53699e91996-12-10 23:23:01 +00005238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005239posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005240{
5241 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005242 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005243 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005244 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005245 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005246 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005247 if (res < 0)
5248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005249 Py_INCREF(Py_None);
5250 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005251}
5252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005254PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005255"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005256Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005257
Barry Warsaw53699e91996-12-10 23:23:01 +00005258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005259posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005260{
5261 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005262#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005263 LONG_LONG pos, res;
5264#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005265 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005266#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005267 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005268 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005269 return NULL;
5270#ifdef SEEK_SET
5271 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5272 switch (how) {
5273 case 0: how = SEEK_SET; break;
5274 case 1: how = SEEK_CUR; break;
5275 case 2: how = SEEK_END; break;
5276 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005277#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005278
5279#if !defined(HAVE_LARGEFILE_SUPPORT)
5280 pos = PyInt_AsLong(posobj);
5281#else
5282 pos = PyLong_Check(posobj) ?
5283 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5284#endif
5285 if (PyErr_Occurred())
5286 return NULL;
5287
Barry Warsaw53699e91996-12-10 23:23:01 +00005288 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005289#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005290 res = _lseeki64(fd, pos, how);
5291#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005292 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005293#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005294 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005295 if (res < 0)
5296 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005297
5298#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005299 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005300#else
5301 return PyLong_FromLongLong(res);
5302#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005303}
5304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005305
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005306PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005307"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005308Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005309
Barry Warsaw53699e91996-12-10 23:23:01 +00005310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005311posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005312{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005313 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005314 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005315 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005316 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005317 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005318 if (buffer == NULL)
5319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005320 Py_BEGIN_ALLOW_THREADS
5321 n = read(fd, PyString_AsString(buffer), size);
5322 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005323 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005324 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005325 return posix_error();
5326 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005327 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005328 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005329 return buffer;
5330}
5331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005334"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005335Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005336
Barry Warsaw53699e91996-12-10 23:23:01 +00005337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005338posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005339{
5340 int fd, size;
5341 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005343 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005344 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005345 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005346 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005347 if (size < 0)
5348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005349 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005350}
5351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Barry Warsaw53699e91996-12-10 23:23:01 +00005357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005358posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005359{
5360 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005361 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005362 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005364 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005365 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005366 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005367 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005368 if (res != 0)
5369 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005370
Fred Drake699f3522000-06-29 21:12:41 +00005371 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005372}
5373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005376"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Barry Warsaw53699e91996-12-10 23:23:01 +00005379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005380posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005381{
Guido van Rossum687dd131993-05-17 08:34:16 +00005382 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005383 char *mode = "r";
5384 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005385 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005386 PyObject *f;
5387 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005388 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005389
Thomas Heller1f043e22002-11-07 16:00:59 +00005390 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5391 PyErr_Format(PyExc_ValueError,
5392 "invalid file mode '%s'", mode);
5393 return NULL;
5394 }
5395
Barry Warsaw53699e91996-12-10 23:23:01 +00005396 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005397 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005398 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005399 if (fp == NULL)
5400 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005401 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005402 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005403 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005404 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005405}
5406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005407PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005408"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005409Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005411
5412static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005413posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005414{
5415 int fd;
5416 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5417 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005418 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005419}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005420
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005421#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005423"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005424Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005425
Barry Warsaw53699e91996-12-10 23:23:01 +00005426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005427posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005428{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005429#if defined(PYOS_OS2)
5430 HFILE read, write;
5431 APIRET rc;
5432
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005433 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005434 return NULL;
5435
5436 Py_BEGIN_ALLOW_THREADS
5437 rc = DosCreatePipe( &read, &write, 4096);
5438 Py_END_ALLOW_THREADS
5439 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005440 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005441
5442 return Py_BuildValue("(ii)", read, write);
5443#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005444#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005445 int fds[2];
5446 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005447 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005448 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005449 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005450#if defined(__VMS)
5451 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5452#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005453 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005454#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005455 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005456 if (res != 0)
5457 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005458 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005459#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005460 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005461 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005462 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005463 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005464 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005465 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005466 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005467 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005468 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005469 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005470 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5471 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005472 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005473#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005474#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005475}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005476#endif /* HAVE_PIPE */
5477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005478
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005479#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005480PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005481"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005483
Barry Warsaw53699e91996-12-10 23:23:01 +00005484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005485posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005486{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005487 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005488 int mode = 0666;
5489 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005490 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005493 res = mkfifo(filename, mode);
5494 Py_END_ALLOW_THREADS
5495 if (res < 0)
5496 return posix_error();
5497 Py_INCREF(Py_None);
5498 return Py_None;
5499}
5500#endif
5501
5502
Neal Norwitz11690112002-07-30 01:08:28 +00005503#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005505"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005506Create a filesystem node (file, device special file or named pipe)\n\
5507named filename. mode specifies both the permissions to use and the\n\
5508type of node to be created, being combined (bitwise OR) with one of\n\
5509S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005510device defines the newly created device special file (probably using\n\
5511os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005512
5513
5514static PyObject *
5515posix_mknod(PyObject *self, PyObject *args)
5516{
5517 char *filename;
5518 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005519 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005520 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005521 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005522 return NULL;
5523 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005524 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005525 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005526 if (res < 0)
5527 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005528 Py_INCREF(Py_None);
5529 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005530}
5531#endif
5532
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005533#ifdef HAVE_DEVICE_MACROS
5534PyDoc_STRVAR(posix_major__doc__,
5535"major(device) -> major number\n\
5536Extracts a device major number from a raw device number.");
5537
5538static PyObject *
5539posix_major(PyObject *self, PyObject *args)
5540{
5541 int device;
5542 if (!PyArg_ParseTuple(args, "i:major", &device))
5543 return NULL;
5544 return PyInt_FromLong((long)major(device));
5545}
5546
5547PyDoc_STRVAR(posix_minor__doc__,
5548"minor(device) -> minor number\n\
5549Extracts a device minor number from a raw device number.");
5550
5551static PyObject *
5552posix_minor(PyObject *self, PyObject *args)
5553{
5554 int device;
5555 if (!PyArg_ParseTuple(args, "i:minor", &device))
5556 return NULL;
5557 return PyInt_FromLong((long)minor(device));
5558}
5559
5560PyDoc_STRVAR(posix_makedev__doc__,
5561"makedev(major, minor) -> device number\n\
5562Composes a raw device number from the major and minor device numbers.");
5563
5564static PyObject *
5565posix_makedev(PyObject *self, PyObject *args)
5566{
5567 int major, minor;
5568 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5569 return NULL;
5570 return PyInt_FromLong((long)makedev(major, minor));
5571}
5572#endif /* device macros */
5573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005574
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005575#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005577"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005579
Barry Warsaw53699e91996-12-10 23:23:01 +00005580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005581posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005582{
5583 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005584 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005585 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005586 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005587
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005588 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005589 return NULL;
5590
5591#if !defined(HAVE_LARGEFILE_SUPPORT)
5592 length = PyInt_AsLong(lenobj);
5593#else
5594 length = PyLong_Check(lenobj) ?
5595 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5596#endif
5597 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005598 return NULL;
5599
Barry Warsaw53699e91996-12-10 23:23:01 +00005600 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005601 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005602 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005603 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005604 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005605 return NULL;
5606 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005607 Py_INCREF(Py_None);
5608 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005609}
5610#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005611
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005612#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005613PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005614"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005616
Fred Drake762e2061999-08-26 17:23:54 +00005617/* Save putenv() parameters as values here, so we can collect them when they
5618 * get re-set with another call for the same key. */
5619static PyObject *posix_putenv_garbage;
5620
Tim Peters5aa91602002-01-30 05:46:57 +00005621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005622posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005623{
5624 char *s1, *s2;
5625 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005626 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005627 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005628
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005629 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005630 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005631
5632#if defined(PYOS_OS2)
5633 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5634 APIRET rc;
5635
5636 if (strlen(s2) == 0) /* If New Value is an Empty String */
5637 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5638
5639 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5640 if (rc != NO_ERROR)
5641 return os2_error(rc);
5642
5643 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5644 APIRET rc;
5645
5646 if (strlen(s2) == 0) /* If New Value is an Empty String */
5647 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5648
5649 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5650 if (rc != NO_ERROR)
5651 return os2_error(rc);
5652 } else {
5653#endif
5654
Fred Drake762e2061999-08-26 17:23:54 +00005655 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005656 len = strlen(s1) + strlen(s2) + 2;
5657 /* len includes space for a trailing \0; the size arg to
5658 PyString_FromStringAndSize does not count that */
5659 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005660 if (newstr == NULL)
5661 return PyErr_NoMemory();
5662 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005663 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005664 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005665 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005666 posix_error();
5667 return NULL;
5668 }
Fred Drake762e2061999-08-26 17:23:54 +00005669 /* Install the first arg and newstr in posix_putenv_garbage;
5670 * this will cause previous value to be collected. This has to
5671 * happen after the real putenv() call because the old value
5672 * was still accessible until then. */
5673 if (PyDict_SetItem(posix_putenv_garbage,
5674 PyTuple_GET_ITEM(args, 0), newstr)) {
5675 /* really not much we can do; just leak */
5676 PyErr_Clear();
5677 }
5678 else {
5679 Py_DECREF(newstr);
5680 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005681
5682#if defined(PYOS_OS2)
5683 }
5684#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005685 Py_INCREF(Py_None);
5686 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005687}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005688#endif /* putenv */
5689
Guido van Rossumc524d952001-10-19 01:31:59 +00005690#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005692"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005694
5695static PyObject *
5696posix_unsetenv(PyObject *self, PyObject *args)
5697{
5698 char *s1;
5699
5700 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5701 return NULL;
5702
5703 unsetenv(s1);
5704
5705 /* Remove the key from posix_putenv_garbage;
5706 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005707 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005708 * old value was still accessible until then.
5709 */
5710 if (PyDict_DelItem(posix_putenv_garbage,
5711 PyTuple_GET_ITEM(args, 0))) {
5712 /* really not much we can do; just leak */
5713 PyErr_Clear();
5714 }
5715
5716 Py_INCREF(Py_None);
5717 return Py_None;
5718}
5719#endif /* unsetenv */
5720
Guido van Rossumb6a47161997-09-15 22:54:34 +00005721#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005723"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005724Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005725
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005727posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005728{
5729 int code;
5730 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005732 return NULL;
5733 message = strerror(code);
5734 if (message == NULL) {
5735 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005736 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005737 return NULL;
5738 }
5739 return PyString_FromString(message);
5740}
5741#endif /* strerror */
5742
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005743
Guido van Rossumc9641791998-08-04 15:26:23 +00005744#ifdef HAVE_SYS_WAIT_H
5745
Fred Drake106c1a02002-04-23 15:58:02 +00005746#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005748"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005749Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005750
5751static PyObject *
5752posix_WCOREDUMP(PyObject *self, PyObject *args)
5753{
5754#ifdef UNION_WAIT
5755 union wait status;
5756#define status_i (status.w_status)
5757#else
5758 int status;
5759#define status_i status
5760#endif
5761 status_i = 0;
5762
5763 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5764 {
5765 return NULL;
5766 }
5767
5768 return PyBool_FromLong(WCOREDUMP(status));
5769#undef status_i
5770}
5771#endif /* WCOREDUMP */
5772
5773#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005775"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005776Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005777job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005778
5779static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005780posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005781{
5782#ifdef UNION_WAIT
5783 union wait status;
5784#define status_i (status.w_status)
5785#else
5786 int status;
5787#define status_i status
5788#endif
5789 status_i = 0;
5790
5791 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5792 {
5793 return NULL;
5794 }
5795
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005796 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005797#undef status_i
5798}
5799#endif /* WIFCONTINUED */
5800
Guido van Rossumc9641791998-08-04 15:26:23 +00005801#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005802PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005803"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005804Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005805
5806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005807posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005808{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005809#ifdef UNION_WAIT
5810 union wait status;
5811#define status_i (status.w_status)
5812#else
5813 int status;
5814#define status_i status
5815#endif
5816 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005817
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005818 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005819 {
5820 return NULL;
5821 }
Tim Peters5aa91602002-01-30 05:46:57 +00005822
Fred Drake106c1a02002-04-23 15:58:02 +00005823 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005824#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005825}
5826#endif /* WIFSTOPPED */
5827
5828#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005829PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005830"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005832
5833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005834posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005835{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005836#ifdef UNION_WAIT
5837 union wait status;
5838#define status_i (status.w_status)
5839#else
5840 int status;
5841#define status_i status
5842#endif
5843 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005844
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005845 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005846 {
5847 return NULL;
5848 }
Tim Peters5aa91602002-01-30 05:46:57 +00005849
Fred Drake106c1a02002-04-23 15:58:02 +00005850 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005851#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005852}
5853#endif /* WIFSIGNALED */
5854
5855#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005856PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005857"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005858Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005859system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005860
5861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005862posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005863{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005864#ifdef UNION_WAIT
5865 union wait status;
5866#define status_i (status.w_status)
5867#else
5868 int status;
5869#define status_i status
5870#endif
5871 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005872
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005873 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005874 {
5875 return NULL;
5876 }
Tim Peters5aa91602002-01-30 05:46:57 +00005877
Fred Drake106c1a02002-04-23 15:58:02 +00005878 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005879#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005880}
5881#endif /* WIFEXITED */
5882
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005883#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005885"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005886Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005887
5888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005889posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005890{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005891#ifdef UNION_WAIT
5892 union wait status;
5893#define status_i (status.w_status)
5894#else
5895 int status;
5896#define status_i status
5897#endif
5898 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005899
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005900 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005901 {
5902 return NULL;
5903 }
Tim Peters5aa91602002-01-30 05:46:57 +00005904
Guido van Rossumc9641791998-08-04 15:26:23 +00005905 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005906#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005907}
5908#endif /* WEXITSTATUS */
5909
5910#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005911PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005912"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005913Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005914value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005915
5916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005917posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005918{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005919#ifdef UNION_WAIT
5920 union wait status;
5921#define status_i (status.w_status)
5922#else
5923 int status;
5924#define status_i status
5925#endif
5926 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005927
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005928 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005929 {
5930 return NULL;
5931 }
Tim Peters5aa91602002-01-30 05:46:57 +00005932
Guido van Rossumc9641791998-08-04 15:26:23 +00005933 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005934#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005935}
5936#endif /* WTERMSIG */
5937
5938#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005939PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005940"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941Return the signal that stopped the process that provided\n\
5942the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005943
5944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005945posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005946{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005947#ifdef UNION_WAIT
5948 union wait status;
5949#define status_i (status.w_status)
5950#else
5951 int status;
5952#define status_i status
5953#endif
5954 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005955
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005956 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005957 {
5958 return NULL;
5959 }
Tim Peters5aa91602002-01-30 05:46:57 +00005960
Guido van Rossumc9641791998-08-04 15:26:23 +00005961 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005962#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005963}
5964#endif /* WSTOPSIG */
5965
5966#endif /* HAVE_SYS_WAIT_H */
5967
5968
Guido van Rossum94f6f721999-01-06 18:42:14 +00005969#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005970#ifdef _SCO_DS
5971/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5972 needed definitions in sys/statvfs.h */
5973#define _SVID3
5974#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005975#include <sys/statvfs.h>
5976
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005977static PyObject*
5978_pystatvfs_fromstructstatvfs(struct statvfs st) {
5979 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5980 if (v == NULL)
5981 return NULL;
5982
5983#if !defined(HAVE_LARGEFILE_SUPPORT)
5984 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5985 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5986 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5987 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5988 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5989 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5990 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5991 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5992 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5993 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5994#else
5995 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5996 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005997 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005998 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005999 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006000 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
6001 PyStructSequence_SET_ITEM(v, 4,
6002 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006003 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006004 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006005 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006006 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006007 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006008 PyLong_FromLongLong((LONG_LONG) st.f_favail));
6009 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6010 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6011#endif
6012
6013 return v;
6014}
6015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006016PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006017"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006018Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006019
6020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006021posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006022{
6023 int fd, res;
6024 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006025
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006026 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006027 return NULL;
6028 Py_BEGIN_ALLOW_THREADS
6029 res = fstatvfs(fd, &st);
6030 Py_END_ALLOW_THREADS
6031 if (res != 0)
6032 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006033
6034 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006035}
6036#endif /* HAVE_FSTATVFS */
6037
6038
6039#if defined(HAVE_STATVFS)
6040#include <sys/statvfs.h>
6041
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006043"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006044Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006045
6046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006047posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006048{
6049 char *path;
6050 int res;
6051 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006052 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006053 return NULL;
6054 Py_BEGIN_ALLOW_THREADS
6055 res = statvfs(path, &st);
6056 Py_END_ALLOW_THREADS
6057 if (res != 0)
6058 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006059
6060 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006061}
6062#endif /* HAVE_STATVFS */
6063
6064
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006065#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006067"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006068Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006069The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006071
6072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006073posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006074{
6075 PyObject *result = NULL;
6076 char *dir = NULL;
6077 char *pfx = NULL;
6078 char *name;
6079
6080 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6081 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006082
6083 if (PyErr_Warn(PyExc_RuntimeWarning,
6084 "tempnam is a potential security risk to your program") < 0)
6085 return NULL;
6086
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006087#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006088 name = _tempnam(dir, pfx);
6089#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006090 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006091#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006092 if (name == NULL)
6093 return PyErr_NoMemory();
6094 result = PyString_FromString(name);
6095 free(name);
6096 return result;
6097}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006098#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006099
6100
6101#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006103"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006105
6106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006107posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006108{
6109 FILE *fp;
6110
6111 if (!PyArg_ParseTuple(args, ":tmpfile"))
6112 return NULL;
6113 fp = tmpfile();
6114 if (fp == NULL)
6115 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006116 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006117}
6118#endif
6119
6120
6121#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006123"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006125
6126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006128{
6129 char buffer[L_tmpnam];
6130 char *name;
6131
6132 if (!PyArg_ParseTuple(args, ":tmpnam"))
6133 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006134
6135 if (PyErr_Warn(PyExc_RuntimeWarning,
6136 "tmpnam is a potential security risk to your program") < 0)
6137 return NULL;
6138
Greg Wardb48bc172000-03-01 21:51:56 +00006139#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006140 name = tmpnam_r(buffer);
6141#else
6142 name = tmpnam(buffer);
6143#endif
6144 if (name == NULL) {
6145 PyErr_SetObject(PyExc_OSError,
6146 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006147#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006148 "unexpected NULL from tmpnam_r"
6149#else
6150 "unexpected NULL from tmpnam"
6151#endif
6152 ));
6153 return NULL;
6154 }
6155 return PyString_FromString(buffer);
6156}
6157#endif
6158
6159
Fred Drakec9680921999-12-13 16:37:25 +00006160/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6161 * It maps strings representing configuration variable names to
6162 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006163 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006164 * rarely-used constants. There are three separate tables that use
6165 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006166 *
6167 * This code is always included, even if none of the interfaces that
6168 * need it are included. The #if hackery needed to avoid it would be
6169 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006170 */
6171struct constdef {
6172 char *name;
6173 long value;
6174};
6175
Fred Drake12c6e2d1999-12-14 21:25:03 +00006176static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006177conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6178 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006179{
6180 if (PyInt_Check(arg)) {
6181 *valuep = PyInt_AS_LONG(arg);
6182 return 1;
6183 }
6184 if (PyString_Check(arg)) {
6185 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006186 size_t lo = 0;
6187 size_t mid;
6188 size_t hi = tablesize;
6189 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006190 char *confname = PyString_AS_STRING(arg);
6191 while (lo < hi) {
6192 mid = (lo + hi) / 2;
6193 cmp = strcmp(confname, table[mid].name);
6194 if (cmp < 0)
6195 hi = mid;
6196 else if (cmp > 0)
6197 lo = mid + 1;
6198 else {
6199 *valuep = table[mid].value;
6200 return 1;
6201 }
6202 }
6203 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6204 }
6205 else
6206 PyErr_SetString(PyExc_TypeError,
6207 "configuration names must be strings or integers");
6208 return 0;
6209}
6210
6211
6212#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6213static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006214#ifdef _PC_ABI_AIO_XFER_MAX
6215 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6216#endif
6217#ifdef _PC_ABI_ASYNC_IO
6218 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6219#endif
Fred Drakec9680921999-12-13 16:37:25 +00006220#ifdef _PC_ASYNC_IO
6221 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6222#endif
6223#ifdef _PC_CHOWN_RESTRICTED
6224 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6225#endif
6226#ifdef _PC_FILESIZEBITS
6227 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6228#endif
6229#ifdef _PC_LAST
6230 {"PC_LAST", _PC_LAST},
6231#endif
6232#ifdef _PC_LINK_MAX
6233 {"PC_LINK_MAX", _PC_LINK_MAX},
6234#endif
6235#ifdef _PC_MAX_CANON
6236 {"PC_MAX_CANON", _PC_MAX_CANON},
6237#endif
6238#ifdef _PC_MAX_INPUT
6239 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6240#endif
6241#ifdef _PC_NAME_MAX
6242 {"PC_NAME_MAX", _PC_NAME_MAX},
6243#endif
6244#ifdef _PC_NO_TRUNC
6245 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6246#endif
6247#ifdef _PC_PATH_MAX
6248 {"PC_PATH_MAX", _PC_PATH_MAX},
6249#endif
6250#ifdef _PC_PIPE_BUF
6251 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6252#endif
6253#ifdef _PC_PRIO_IO
6254 {"PC_PRIO_IO", _PC_PRIO_IO},
6255#endif
6256#ifdef _PC_SOCK_MAXBUF
6257 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6258#endif
6259#ifdef _PC_SYNC_IO
6260 {"PC_SYNC_IO", _PC_SYNC_IO},
6261#endif
6262#ifdef _PC_VDISABLE
6263 {"PC_VDISABLE", _PC_VDISABLE},
6264#endif
6265};
6266
Fred Drakec9680921999-12-13 16:37:25 +00006267static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006268conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006269{
6270 return conv_confname(arg, valuep, posix_constants_pathconf,
6271 sizeof(posix_constants_pathconf)
6272 / sizeof(struct constdef));
6273}
6274#endif
6275
6276#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006278"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006279Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006280If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006281
6282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006283posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006284{
6285 PyObject *result = NULL;
6286 int name, fd;
6287
Fred Drake12c6e2d1999-12-14 21:25:03 +00006288 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6289 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006290 long limit;
6291
6292 errno = 0;
6293 limit = fpathconf(fd, name);
6294 if (limit == -1 && errno != 0)
6295 posix_error();
6296 else
6297 result = PyInt_FromLong(limit);
6298 }
6299 return result;
6300}
6301#endif
6302
6303
6304#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006306"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006307Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006309
6310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006311posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006312{
6313 PyObject *result = NULL;
6314 int name;
6315 char *path;
6316
6317 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6318 conv_path_confname, &name)) {
6319 long limit;
6320
6321 errno = 0;
6322 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006323 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006324 if (errno == EINVAL)
6325 /* could be a path or name problem */
6326 posix_error();
6327 else
6328 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006329 }
Fred Drakec9680921999-12-13 16:37:25 +00006330 else
6331 result = PyInt_FromLong(limit);
6332 }
6333 return result;
6334}
6335#endif
6336
6337#ifdef HAVE_CONFSTR
6338static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006339#ifdef _CS_ARCHITECTURE
6340 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6341#endif
6342#ifdef _CS_HOSTNAME
6343 {"CS_HOSTNAME", _CS_HOSTNAME},
6344#endif
6345#ifdef _CS_HW_PROVIDER
6346 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6347#endif
6348#ifdef _CS_HW_SERIAL
6349 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6350#endif
6351#ifdef _CS_INITTAB_NAME
6352 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6353#endif
Fred Drakec9680921999-12-13 16:37:25 +00006354#ifdef _CS_LFS64_CFLAGS
6355 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6356#endif
6357#ifdef _CS_LFS64_LDFLAGS
6358 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6359#endif
6360#ifdef _CS_LFS64_LIBS
6361 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6362#endif
6363#ifdef _CS_LFS64_LINTFLAGS
6364 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6365#endif
6366#ifdef _CS_LFS_CFLAGS
6367 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6368#endif
6369#ifdef _CS_LFS_LDFLAGS
6370 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6371#endif
6372#ifdef _CS_LFS_LIBS
6373 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6374#endif
6375#ifdef _CS_LFS_LINTFLAGS
6376 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6377#endif
Fred Draked86ed291999-12-15 15:34:33 +00006378#ifdef _CS_MACHINE
6379 {"CS_MACHINE", _CS_MACHINE},
6380#endif
Fred Drakec9680921999-12-13 16:37:25 +00006381#ifdef _CS_PATH
6382 {"CS_PATH", _CS_PATH},
6383#endif
Fred Draked86ed291999-12-15 15:34:33 +00006384#ifdef _CS_RELEASE
6385 {"CS_RELEASE", _CS_RELEASE},
6386#endif
6387#ifdef _CS_SRPC_DOMAIN
6388 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6389#endif
6390#ifdef _CS_SYSNAME
6391 {"CS_SYSNAME", _CS_SYSNAME},
6392#endif
6393#ifdef _CS_VERSION
6394 {"CS_VERSION", _CS_VERSION},
6395#endif
Fred Drakec9680921999-12-13 16:37:25 +00006396#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6397 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6398#endif
6399#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6400 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6401#endif
6402#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6403 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6404#endif
6405#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6406 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6407#endif
6408#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6409 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6410#endif
6411#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6412 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6413#endif
6414#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6415 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6416#endif
6417#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6418 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6419#endif
6420#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6421 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6422#endif
6423#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6424 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6425#endif
6426#ifdef _CS_XBS5_LP64_OFF64_LIBS
6427 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6428#endif
6429#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6430 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6431#endif
6432#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6433 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6434#endif
6435#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6436 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6437#endif
6438#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6439 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6440#endif
6441#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6442 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6443#endif
Fred Draked86ed291999-12-15 15:34:33 +00006444#ifdef _MIPS_CS_AVAIL_PROCESSORS
6445 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6446#endif
6447#ifdef _MIPS_CS_BASE
6448 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6449#endif
6450#ifdef _MIPS_CS_HOSTID
6451 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6452#endif
6453#ifdef _MIPS_CS_HW_NAME
6454 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6455#endif
6456#ifdef _MIPS_CS_NUM_PROCESSORS
6457 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6458#endif
6459#ifdef _MIPS_CS_OSREL_MAJ
6460 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6461#endif
6462#ifdef _MIPS_CS_OSREL_MIN
6463 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6464#endif
6465#ifdef _MIPS_CS_OSREL_PATCH
6466 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6467#endif
6468#ifdef _MIPS_CS_OS_NAME
6469 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6470#endif
6471#ifdef _MIPS_CS_OS_PROVIDER
6472 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6473#endif
6474#ifdef _MIPS_CS_PROCESSORS
6475 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6476#endif
6477#ifdef _MIPS_CS_SERIAL
6478 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6479#endif
6480#ifdef _MIPS_CS_VENDOR
6481 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6482#endif
Fred Drakec9680921999-12-13 16:37:25 +00006483};
6484
6485static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006486conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006487{
6488 return conv_confname(arg, valuep, posix_constants_confstr,
6489 sizeof(posix_constants_confstr)
6490 / sizeof(struct constdef));
6491}
6492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006494"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006495Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006496
6497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006498posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006499{
6500 PyObject *result = NULL;
6501 int name;
6502 char buffer[64];
6503
6504 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6505 int len = confstr(name, buffer, sizeof(buffer));
6506
Fred Drakec9680921999-12-13 16:37:25 +00006507 errno = 0;
6508 if (len == 0) {
6509 if (errno != 0)
6510 posix_error();
6511 else
6512 result = PyString_FromString("");
6513 }
6514 else {
6515 if (len >= sizeof(buffer)) {
6516 result = PyString_FromStringAndSize(NULL, len);
6517 if (result != NULL)
6518 confstr(name, PyString_AS_STRING(result), len+1);
6519 }
6520 else
6521 result = PyString_FromString(buffer);
6522 }
6523 }
6524 return result;
6525}
6526#endif
6527
6528
6529#ifdef HAVE_SYSCONF
6530static struct constdef posix_constants_sysconf[] = {
6531#ifdef _SC_2_CHAR_TERM
6532 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6533#endif
6534#ifdef _SC_2_C_BIND
6535 {"SC_2_C_BIND", _SC_2_C_BIND},
6536#endif
6537#ifdef _SC_2_C_DEV
6538 {"SC_2_C_DEV", _SC_2_C_DEV},
6539#endif
6540#ifdef _SC_2_C_VERSION
6541 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6542#endif
6543#ifdef _SC_2_FORT_DEV
6544 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6545#endif
6546#ifdef _SC_2_FORT_RUN
6547 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6548#endif
6549#ifdef _SC_2_LOCALEDEF
6550 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6551#endif
6552#ifdef _SC_2_SW_DEV
6553 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6554#endif
6555#ifdef _SC_2_UPE
6556 {"SC_2_UPE", _SC_2_UPE},
6557#endif
6558#ifdef _SC_2_VERSION
6559 {"SC_2_VERSION", _SC_2_VERSION},
6560#endif
Fred Draked86ed291999-12-15 15:34:33 +00006561#ifdef _SC_ABI_ASYNCHRONOUS_IO
6562 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6563#endif
6564#ifdef _SC_ACL
6565 {"SC_ACL", _SC_ACL},
6566#endif
Fred Drakec9680921999-12-13 16:37:25 +00006567#ifdef _SC_AIO_LISTIO_MAX
6568 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6569#endif
Fred Drakec9680921999-12-13 16:37:25 +00006570#ifdef _SC_AIO_MAX
6571 {"SC_AIO_MAX", _SC_AIO_MAX},
6572#endif
6573#ifdef _SC_AIO_PRIO_DELTA_MAX
6574 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6575#endif
6576#ifdef _SC_ARG_MAX
6577 {"SC_ARG_MAX", _SC_ARG_MAX},
6578#endif
6579#ifdef _SC_ASYNCHRONOUS_IO
6580 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6581#endif
6582#ifdef _SC_ATEXIT_MAX
6583 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6584#endif
Fred Draked86ed291999-12-15 15:34:33 +00006585#ifdef _SC_AUDIT
6586 {"SC_AUDIT", _SC_AUDIT},
6587#endif
Fred Drakec9680921999-12-13 16:37:25 +00006588#ifdef _SC_AVPHYS_PAGES
6589 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6590#endif
6591#ifdef _SC_BC_BASE_MAX
6592 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6593#endif
6594#ifdef _SC_BC_DIM_MAX
6595 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6596#endif
6597#ifdef _SC_BC_SCALE_MAX
6598 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6599#endif
6600#ifdef _SC_BC_STRING_MAX
6601 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6602#endif
Fred Draked86ed291999-12-15 15:34:33 +00006603#ifdef _SC_CAP
6604 {"SC_CAP", _SC_CAP},
6605#endif
Fred Drakec9680921999-12-13 16:37:25 +00006606#ifdef _SC_CHARCLASS_NAME_MAX
6607 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6608#endif
6609#ifdef _SC_CHAR_BIT
6610 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6611#endif
6612#ifdef _SC_CHAR_MAX
6613 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6614#endif
6615#ifdef _SC_CHAR_MIN
6616 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6617#endif
6618#ifdef _SC_CHILD_MAX
6619 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6620#endif
6621#ifdef _SC_CLK_TCK
6622 {"SC_CLK_TCK", _SC_CLK_TCK},
6623#endif
6624#ifdef _SC_COHER_BLKSZ
6625 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6626#endif
6627#ifdef _SC_COLL_WEIGHTS_MAX
6628 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6629#endif
6630#ifdef _SC_DCACHE_ASSOC
6631 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6632#endif
6633#ifdef _SC_DCACHE_BLKSZ
6634 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6635#endif
6636#ifdef _SC_DCACHE_LINESZ
6637 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6638#endif
6639#ifdef _SC_DCACHE_SZ
6640 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6641#endif
6642#ifdef _SC_DCACHE_TBLKSZ
6643 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6644#endif
6645#ifdef _SC_DELAYTIMER_MAX
6646 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6647#endif
6648#ifdef _SC_EQUIV_CLASS_MAX
6649 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6650#endif
6651#ifdef _SC_EXPR_NEST_MAX
6652 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6653#endif
6654#ifdef _SC_FSYNC
6655 {"SC_FSYNC", _SC_FSYNC},
6656#endif
6657#ifdef _SC_GETGR_R_SIZE_MAX
6658 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6659#endif
6660#ifdef _SC_GETPW_R_SIZE_MAX
6661 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6662#endif
6663#ifdef _SC_ICACHE_ASSOC
6664 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6665#endif
6666#ifdef _SC_ICACHE_BLKSZ
6667 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6668#endif
6669#ifdef _SC_ICACHE_LINESZ
6670 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6671#endif
6672#ifdef _SC_ICACHE_SZ
6673 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6674#endif
Fred Draked86ed291999-12-15 15:34:33 +00006675#ifdef _SC_INF
6676 {"SC_INF", _SC_INF},
6677#endif
Fred Drakec9680921999-12-13 16:37:25 +00006678#ifdef _SC_INT_MAX
6679 {"SC_INT_MAX", _SC_INT_MAX},
6680#endif
6681#ifdef _SC_INT_MIN
6682 {"SC_INT_MIN", _SC_INT_MIN},
6683#endif
6684#ifdef _SC_IOV_MAX
6685 {"SC_IOV_MAX", _SC_IOV_MAX},
6686#endif
Fred Draked86ed291999-12-15 15:34:33 +00006687#ifdef _SC_IP_SECOPTS
6688 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6689#endif
Fred Drakec9680921999-12-13 16:37:25 +00006690#ifdef _SC_JOB_CONTROL
6691 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6692#endif
Fred Draked86ed291999-12-15 15:34:33 +00006693#ifdef _SC_KERN_POINTERS
6694 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6695#endif
6696#ifdef _SC_KERN_SIM
6697 {"SC_KERN_SIM", _SC_KERN_SIM},
6698#endif
Fred Drakec9680921999-12-13 16:37:25 +00006699#ifdef _SC_LINE_MAX
6700 {"SC_LINE_MAX", _SC_LINE_MAX},
6701#endif
6702#ifdef _SC_LOGIN_NAME_MAX
6703 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6704#endif
6705#ifdef _SC_LOGNAME_MAX
6706 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6707#endif
6708#ifdef _SC_LONG_BIT
6709 {"SC_LONG_BIT", _SC_LONG_BIT},
6710#endif
Fred Draked86ed291999-12-15 15:34:33 +00006711#ifdef _SC_MAC
6712 {"SC_MAC", _SC_MAC},
6713#endif
Fred Drakec9680921999-12-13 16:37:25 +00006714#ifdef _SC_MAPPED_FILES
6715 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6716#endif
6717#ifdef _SC_MAXPID
6718 {"SC_MAXPID", _SC_MAXPID},
6719#endif
6720#ifdef _SC_MB_LEN_MAX
6721 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6722#endif
6723#ifdef _SC_MEMLOCK
6724 {"SC_MEMLOCK", _SC_MEMLOCK},
6725#endif
6726#ifdef _SC_MEMLOCK_RANGE
6727 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6728#endif
6729#ifdef _SC_MEMORY_PROTECTION
6730 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6731#endif
6732#ifdef _SC_MESSAGE_PASSING
6733 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6734#endif
Fred Draked86ed291999-12-15 15:34:33 +00006735#ifdef _SC_MMAP_FIXED_ALIGNMENT
6736 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6737#endif
Fred Drakec9680921999-12-13 16:37:25 +00006738#ifdef _SC_MQ_OPEN_MAX
6739 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6740#endif
6741#ifdef _SC_MQ_PRIO_MAX
6742 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6743#endif
Fred Draked86ed291999-12-15 15:34:33 +00006744#ifdef _SC_NACLS_MAX
6745 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6746#endif
Fred Drakec9680921999-12-13 16:37:25 +00006747#ifdef _SC_NGROUPS_MAX
6748 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6749#endif
6750#ifdef _SC_NL_ARGMAX
6751 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6752#endif
6753#ifdef _SC_NL_LANGMAX
6754 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6755#endif
6756#ifdef _SC_NL_MSGMAX
6757 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6758#endif
6759#ifdef _SC_NL_NMAX
6760 {"SC_NL_NMAX", _SC_NL_NMAX},
6761#endif
6762#ifdef _SC_NL_SETMAX
6763 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6764#endif
6765#ifdef _SC_NL_TEXTMAX
6766 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6767#endif
6768#ifdef _SC_NPROCESSORS_CONF
6769 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6770#endif
6771#ifdef _SC_NPROCESSORS_ONLN
6772 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6773#endif
Fred Draked86ed291999-12-15 15:34:33 +00006774#ifdef _SC_NPROC_CONF
6775 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6776#endif
6777#ifdef _SC_NPROC_ONLN
6778 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6779#endif
Fred Drakec9680921999-12-13 16:37:25 +00006780#ifdef _SC_NZERO
6781 {"SC_NZERO", _SC_NZERO},
6782#endif
6783#ifdef _SC_OPEN_MAX
6784 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6785#endif
6786#ifdef _SC_PAGESIZE
6787 {"SC_PAGESIZE", _SC_PAGESIZE},
6788#endif
6789#ifdef _SC_PAGE_SIZE
6790 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6791#endif
6792#ifdef _SC_PASS_MAX
6793 {"SC_PASS_MAX", _SC_PASS_MAX},
6794#endif
6795#ifdef _SC_PHYS_PAGES
6796 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6797#endif
6798#ifdef _SC_PII
6799 {"SC_PII", _SC_PII},
6800#endif
6801#ifdef _SC_PII_INTERNET
6802 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6803#endif
6804#ifdef _SC_PII_INTERNET_DGRAM
6805 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6806#endif
6807#ifdef _SC_PII_INTERNET_STREAM
6808 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6809#endif
6810#ifdef _SC_PII_OSI
6811 {"SC_PII_OSI", _SC_PII_OSI},
6812#endif
6813#ifdef _SC_PII_OSI_CLTS
6814 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6815#endif
6816#ifdef _SC_PII_OSI_COTS
6817 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6818#endif
6819#ifdef _SC_PII_OSI_M
6820 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6821#endif
6822#ifdef _SC_PII_SOCKET
6823 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6824#endif
6825#ifdef _SC_PII_XTI
6826 {"SC_PII_XTI", _SC_PII_XTI},
6827#endif
6828#ifdef _SC_POLL
6829 {"SC_POLL", _SC_POLL},
6830#endif
6831#ifdef _SC_PRIORITIZED_IO
6832 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6833#endif
6834#ifdef _SC_PRIORITY_SCHEDULING
6835 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6836#endif
6837#ifdef _SC_REALTIME_SIGNALS
6838 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6839#endif
6840#ifdef _SC_RE_DUP_MAX
6841 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6842#endif
6843#ifdef _SC_RTSIG_MAX
6844 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6845#endif
6846#ifdef _SC_SAVED_IDS
6847 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6848#endif
6849#ifdef _SC_SCHAR_MAX
6850 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6851#endif
6852#ifdef _SC_SCHAR_MIN
6853 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6854#endif
6855#ifdef _SC_SELECT
6856 {"SC_SELECT", _SC_SELECT},
6857#endif
6858#ifdef _SC_SEMAPHORES
6859 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6860#endif
6861#ifdef _SC_SEM_NSEMS_MAX
6862 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6863#endif
6864#ifdef _SC_SEM_VALUE_MAX
6865 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6866#endif
6867#ifdef _SC_SHARED_MEMORY_OBJECTS
6868 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6869#endif
6870#ifdef _SC_SHRT_MAX
6871 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6872#endif
6873#ifdef _SC_SHRT_MIN
6874 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6875#endif
6876#ifdef _SC_SIGQUEUE_MAX
6877 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6878#endif
6879#ifdef _SC_SIGRT_MAX
6880 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6881#endif
6882#ifdef _SC_SIGRT_MIN
6883 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6884#endif
Fred Draked86ed291999-12-15 15:34:33 +00006885#ifdef _SC_SOFTPOWER
6886 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6887#endif
Fred Drakec9680921999-12-13 16:37:25 +00006888#ifdef _SC_SPLIT_CACHE
6889 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6890#endif
6891#ifdef _SC_SSIZE_MAX
6892 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6893#endif
6894#ifdef _SC_STACK_PROT
6895 {"SC_STACK_PROT", _SC_STACK_PROT},
6896#endif
6897#ifdef _SC_STREAM_MAX
6898 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6899#endif
6900#ifdef _SC_SYNCHRONIZED_IO
6901 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6902#endif
6903#ifdef _SC_THREADS
6904 {"SC_THREADS", _SC_THREADS},
6905#endif
6906#ifdef _SC_THREAD_ATTR_STACKADDR
6907 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6908#endif
6909#ifdef _SC_THREAD_ATTR_STACKSIZE
6910 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6911#endif
6912#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6913 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6914#endif
6915#ifdef _SC_THREAD_KEYS_MAX
6916 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6917#endif
6918#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6919 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6920#endif
6921#ifdef _SC_THREAD_PRIO_INHERIT
6922 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6923#endif
6924#ifdef _SC_THREAD_PRIO_PROTECT
6925 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6926#endif
6927#ifdef _SC_THREAD_PROCESS_SHARED
6928 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6929#endif
6930#ifdef _SC_THREAD_SAFE_FUNCTIONS
6931 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6932#endif
6933#ifdef _SC_THREAD_STACK_MIN
6934 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6935#endif
6936#ifdef _SC_THREAD_THREADS_MAX
6937 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6938#endif
6939#ifdef _SC_TIMERS
6940 {"SC_TIMERS", _SC_TIMERS},
6941#endif
6942#ifdef _SC_TIMER_MAX
6943 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6944#endif
6945#ifdef _SC_TTY_NAME_MAX
6946 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6947#endif
6948#ifdef _SC_TZNAME_MAX
6949 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6950#endif
6951#ifdef _SC_T_IOV_MAX
6952 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6953#endif
6954#ifdef _SC_UCHAR_MAX
6955 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6956#endif
6957#ifdef _SC_UINT_MAX
6958 {"SC_UINT_MAX", _SC_UINT_MAX},
6959#endif
6960#ifdef _SC_UIO_MAXIOV
6961 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6962#endif
6963#ifdef _SC_ULONG_MAX
6964 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6965#endif
6966#ifdef _SC_USHRT_MAX
6967 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6968#endif
6969#ifdef _SC_VERSION
6970 {"SC_VERSION", _SC_VERSION},
6971#endif
6972#ifdef _SC_WORD_BIT
6973 {"SC_WORD_BIT", _SC_WORD_BIT},
6974#endif
6975#ifdef _SC_XBS5_ILP32_OFF32
6976 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6977#endif
6978#ifdef _SC_XBS5_ILP32_OFFBIG
6979 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6980#endif
6981#ifdef _SC_XBS5_LP64_OFF64
6982 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6983#endif
6984#ifdef _SC_XBS5_LPBIG_OFFBIG
6985 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6986#endif
6987#ifdef _SC_XOPEN_CRYPT
6988 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6989#endif
6990#ifdef _SC_XOPEN_ENH_I18N
6991 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6992#endif
6993#ifdef _SC_XOPEN_LEGACY
6994 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6995#endif
6996#ifdef _SC_XOPEN_REALTIME
6997 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6998#endif
6999#ifdef _SC_XOPEN_REALTIME_THREADS
7000 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7001#endif
7002#ifdef _SC_XOPEN_SHM
7003 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7004#endif
7005#ifdef _SC_XOPEN_UNIX
7006 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7007#endif
7008#ifdef _SC_XOPEN_VERSION
7009 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7010#endif
7011#ifdef _SC_XOPEN_XCU_VERSION
7012 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7013#endif
7014#ifdef _SC_XOPEN_XPG2
7015 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7016#endif
7017#ifdef _SC_XOPEN_XPG3
7018 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7019#endif
7020#ifdef _SC_XOPEN_XPG4
7021 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7022#endif
7023};
7024
7025static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007026conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007027{
7028 return conv_confname(arg, valuep, posix_constants_sysconf,
7029 sizeof(posix_constants_sysconf)
7030 / sizeof(struct constdef));
7031}
7032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007034"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007035Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007036
7037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007038posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007039{
7040 PyObject *result = NULL;
7041 int name;
7042
7043 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7044 int value;
7045
7046 errno = 0;
7047 value = sysconf(name);
7048 if (value == -1 && errno != 0)
7049 posix_error();
7050 else
7051 result = PyInt_FromLong(value);
7052 }
7053 return result;
7054}
7055#endif
7056
7057
Fred Drakebec628d1999-12-15 18:31:10 +00007058/* This code is used to ensure that the tables of configuration value names
7059 * are in sorted order as required by conv_confname(), and also to build the
7060 * the exported dictionaries that are used to publish information about the
7061 * names available on the host platform.
7062 *
7063 * Sorting the table at runtime ensures that the table is properly ordered
7064 * when used, even for platforms we're not able to test on. It also makes
7065 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007066 */
Fred Drakebec628d1999-12-15 18:31:10 +00007067
7068static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007069cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007070{
7071 const struct constdef *c1 =
7072 (const struct constdef *) v1;
7073 const struct constdef *c2 =
7074 (const struct constdef *) v2;
7075
7076 return strcmp(c1->name, c2->name);
7077}
7078
7079static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007080setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007081 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007082{
Fred Drakebec628d1999-12-15 18:31:10 +00007083 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007084 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007085
7086 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7087 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007088 if (d == NULL)
7089 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007090
Barry Warsaw3155db32000-04-13 15:20:40 +00007091 for (i=0; i < tablesize; ++i) {
7092 PyObject *o = PyInt_FromLong(table[i].value);
7093 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7094 Py_XDECREF(o);
7095 Py_DECREF(d);
7096 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007097 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007098 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007099 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007100 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007101}
7102
Fred Drakebec628d1999-12-15 18:31:10 +00007103/* Return -1 on failure, 0 on success. */
7104static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007105setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007106{
7107#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007108 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007109 sizeof(posix_constants_pathconf)
7110 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007111 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007112 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007113#endif
7114#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007115 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007116 sizeof(posix_constants_confstr)
7117 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007118 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007119 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007120#endif
7121#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007122 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007123 sizeof(posix_constants_sysconf)
7124 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007125 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007126 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007127#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007128 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007129}
Fred Draked86ed291999-12-15 15:34:33 +00007130
7131
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007132PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007133"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007135in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007136
7137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007138posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007139{
7140 if (!PyArg_ParseTuple(args, ":abort"))
7141 return NULL;
7142 abort();
7143 /*NOTREACHED*/
7144 Py_FatalError("abort() called from Python code didn't abort!");
7145 return NULL;
7146}
Fred Drakebec628d1999-12-15 18:31:10 +00007147
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007148#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007149PyDoc_STRVAR(win32_startfile__doc__,
7150"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007151\n\
7152This acts like double-clicking the file in Explorer, or giving the file\n\
7153name as an argument to the DOS \"start\" command: the file is opened\n\
7154with whatever application (if any) its extension is associated.\n\
7155\n\
7156startfile returns as soon as the associated application is launched.\n\
7157There is no option to wait for the application to close, and no way\n\
7158to retrieve the application's exit status.\n\
7159\n\
7160The filepath is relative to the current directory. If you want to use\n\
7161an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007162the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007163
7164static PyObject *
7165win32_startfile(PyObject *self, PyObject *args)
7166{
7167 char *filepath;
7168 HINSTANCE rc;
7169 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7170 return NULL;
7171 Py_BEGIN_ALLOW_THREADS
7172 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7173 Py_END_ALLOW_THREADS
7174 if (rc <= (HINSTANCE)32)
7175 return win32_error("startfile", filepath);
7176 Py_INCREF(Py_None);
7177 return Py_None;
7178}
7179#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007180
Martin v. Löwis438b5342002-12-27 10:16:42 +00007181#ifdef HAVE_GETLOADAVG
7182PyDoc_STRVAR(posix_getloadavg__doc__,
7183"getloadavg() -> (float, float, float)\n\n\
7184Return the number of processes in the system run queue averaged over\n\
7185the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7186was unobtainable");
7187
7188static PyObject *
7189posix_getloadavg(PyObject *self, PyObject *args)
7190{
7191 double loadavg[3];
7192 if (!PyArg_ParseTuple(args, ":getloadavg"))
7193 return NULL;
7194 if (getloadavg(loadavg, 3)!=3) {
7195 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7196 return NULL;
7197 } else
7198 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7199}
7200#endif
7201
7202
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203static PyMethodDef posix_methods[] = {
7204 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7205#ifdef HAVE_TTYNAME
7206 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7207#endif
7208 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7209 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007210#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007211 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007212#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007213#ifdef HAVE_LCHOWN
7214 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7215#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007216#ifdef HAVE_CHROOT
7217 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7218#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007219#ifdef HAVE_CTERMID
7220 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
7221#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007222#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007223 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007224#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007225 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007226#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007227#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007228#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007229 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007230#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007231 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7232 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7233 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007234#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007235 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007236#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007237#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007238 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007239#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007240 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7241 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7242 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007243 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007244#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007245 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007246#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007247#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007248 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007249#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007250 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007251#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007252 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007253#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007254 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7255 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7256 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007257#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007258 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007259#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007260 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007261#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007262 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7263 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007264#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007265#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007266 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7267 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007268#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007269#ifdef HAVE_FORK1
7270 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
7271#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007272#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007273 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007274#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007275#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007276 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007277#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007278#ifdef HAVE_FORKPTY
7279 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
7280#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007281#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007282 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007283#endif /* HAVE_GETEGID */
7284#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007285 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007286#endif /* HAVE_GETEUID */
7287#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007288 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007289#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007290#ifdef HAVE_GETGROUPS
7291 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
7292#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007293 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007294#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007295 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007296#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007297#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007298 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007299#endif /* HAVE_GETPPID */
7300#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007301 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007302#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007303#ifdef HAVE_GETLOGIN
7304 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
7305#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007306#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007307 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007308#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007309#ifdef HAVE_KILLPG
7310 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7311#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007312#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007313 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007314#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007315#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007316 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007317#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007318 {"popen2", win32_popen2, METH_VARARGS},
7319 {"popen3", win32_popen3, METH_VARARGS},
7320 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007321 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007322#else
7323#if defined(PYOS_OS2) && defined(PYCC_GCC)
7324 {"popen2", os2emx_popen2, METH_VARARGS},
7325 {"popen3", os2emx_popen3, METH_VARARGS},
7326 {"popen4", os2emx_popen4, METH_VARARGS},
7327#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007328#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007329#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007330#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007332#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007333#ifdef HAVE_SETEUID
7334 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7335#endif /* HAVE_SETEUID */
7336#ifdef HAVE_SETEGID
7337 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7338#endif /* HAVE_SETEGID */
7339#ifdef HAVE_SETREUID
7340 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7341#endif /* HAVE_SETREUID */
7342#ifdef HAVE_SETREGID
7343 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7344#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007345#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007346 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007347#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007348#ifdef HAVE_SETGROUPS
7349 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7350#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007351#ifdef HAVE_GETPGID
7352 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7353#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007354#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007355 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007356#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007357#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007358 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007359#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007360#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007361 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007362#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007363#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007364 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007365#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007366#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007368#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007369#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007370 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007371#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007372#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007374#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007375 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7376 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7377 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7378 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7379 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7380 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7381 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7382 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7383 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007384 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007385#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007387#endif
7388#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007390#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007391#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007392 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7393#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007394#ifdef HAVE_DEVICE_MACROS
7395 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7396 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7397 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7398#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007399#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007400 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007401#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007402#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007403 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007404#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007405#ifdef HAVE_UNSETENV
7406 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7407#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007408#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007409 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007410#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007411#ifdef HAVE_FCHDIR
7412 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7413#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007414#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007415 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007416#endif
7417#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007418 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007419#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007420#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007421#ifdef WCOREDUMP
7422 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7423#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007424#ifdef WIFCONTINUED
7425 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7426#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007427#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007428 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007429#endif /* WIFSTOPPED */
7430#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007431 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007432#endif /* WIFSIGNALED */
7433#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007434 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007435#endif /* WIFEXITED */
7436#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007437 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007438#endif /* WEXITSTATUS */
7439#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007440 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007441#endif /* WTERMSIG */
7442#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007443 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007444#endif /* WSTOPSIG */
7445#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007446#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007447 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007448#endif
7449#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007450 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007451#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007452#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007453 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7454#endif
7455#ifdef HAVE_TEMPNAM
7456 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7457#endif
7458#ifdef HAVE_TMPNAM
7459 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7460#endif
Fred Drakec9680921999-12-13 16:37:25 +00007461#ifdef HAVE_CONFSTR
7462 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7463#endif
7464#ifdef HAVE_SYSCONF
7465 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7466#endif
7467#ifdef HAVE_FPATHCONF
7468 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7469#endif
7470#ifdef HAVE_PATHCONF
7471 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7472#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007473 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007474#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007475 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7476#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007477#ifdef HAVE_GETLOADAVG
7478 {"getloadavg", posix_getloadavg, METH_VARARGS, posix_getloadavg__doc__},
7479#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007480 {NULL, NULL} /* Sentinel */
7481};
7482
7483
Barry Warsaw4a342091996-12-19 23:50:02 +00007484static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007485ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007486{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007487 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007488}
7489
Guido van Rossumd48f2521997-12-05 22:19:34 +00007490#if defined(PYOS_OS2)
7491/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007492static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007493{
7494 APIRET rc;
7495 ULONG values[QSV_MAX+1];
7496 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007497 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007498
7499 Py_BEGIN_ALLOW_THREADS
7500 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7501 Py_END_ALLOW_THREADS
7502
7503 if (rc != NO_ERROR) {
7504 os2_error(rc);
7505 return -1;
7506 }
7507
Fred Drake4d1e64b2002-04-15 19:40:07 +00007508 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7509 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7510 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7511 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7512 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7513 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7514 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007515
7516 switch (values[QSV_VERSION_MINOR]) {
7517 case 0: ver = "2.00"; break;
7518 case 10: ver = "2.10"; break;
7519 case 11: ver = "2.11"; break;
7520 case 30: ver = "3.00"; break;
7521 case 40: ver = "4.00"; break;
7522 case 50: ver = "5.00"; break;
7523 default:
Tim Peters885d4572001-11-28 20:27:42 +00007524 PyOS_snprintf(tmp, sizeof(tmp),
7525 "%d-%d", values[QSV_VERSION_MAJOR],
7526 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007527 ver = &tmp[0];
7528 }
7529
7530 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007531 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007532 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007533
7534 /* Add Indicator of Which Drive was Used to Boot the System */
7535 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7536 tmp[1] = ':';
7537 tmp[2] = '\0';
7538
Fred Drake4d1e64b2002-04-15 19:40:07 +00007539 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007540}
7541#endif
7542
Barry Warsaw4a342091996-12-19 23:50:02 +00007543static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007544all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007545{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007546#ifdef F_OK
7547 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007548#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007549#ifdef R_OK
7550 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007551#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007552#ifdef W_OK
7553 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007554#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007555#ifdef X_OK
7556 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007557#endif
Fred Drakec9680921999-12-13 16:37:25 +00007558#ifdef NGROUPS_MAX
7559 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7560#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007561#ifdef TMP_MAX
7562 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7563#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007564#ifdef WCONTINUED
7565 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7566#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007567#ifdef WNOHANG
7568 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007569#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007570#ifdef WUNTRACED
7571 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7572#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007573#ifdef O_RDONLY
7574 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7575#endif
7576#ifdef O_WRONLY
7577 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7578#endif
7579#ifdef O_RDWR
7580 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7581#endif
7582#ifdef O_NDELAY
7583 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7584#endif
7585#ifdef O_NONBLOCK
7586 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7587#endif
7588#ifdef O_APPEND
7589 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7590#endif
7591#ifdef O_DSYNC
7592 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7593#endif
7594#ifdef O_RSYNC
7595 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7596#endif
7597#ifdef O_SYNC
7598 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7599#endif
7600#ifdef O_NOCTTY
7601 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7602#endif
7603#ifdef O_CREAT
7604 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7605#endif
7606#ifdef O_EXCL
7607 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7608#endif
7609#ifdef O_TRUNC
7610 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7611#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007612#ifdef O_BINARY
7613 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7614#endif
7615#ifdef O_TEXT
7616 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7617#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007618#ifdef O_LARGEFILE
7619 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7620#endif
7621
Tim Peters5aa91602002-01-30 05:46:57 +00007622/* MS Windows */
7623#ifdef O_NOINHERIT
7624 /* Don't inherit in child processes. */
7625 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7626#endif
7627#ifdef _O_SHORT_LIVED
7628 /* Optimize for short life (keep in memory). */
7629 /* MS forgot to define this one with a non-underscore form too. */
7630 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7631#endif
7632#ifdef O_TEMPORARY
7633 /* Automatically delete when last handle is closed. */
7634 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7635#endif
7636#ifdef O_RANDOM
7637 /* Optimize for random access. */
7638 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7639#endif
7640#ifdef O_SEQUENTIAL
7641 /* Optimize for sequential access. */
7642 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7643#endif
7644
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007645/* GNU extensions. */
7646#ifdef O_DIRECT
7647 /* Direct disk access. */
7648 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7649#endif
7650#ifdef O_DIRECTORY
7651 /* Must be a directory. */
7652 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7653#endif
7654#ifdef O_NOFOLLOW
7655 /* Do not follow links. */
7656 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7657#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007658
Barry Warsaw5676bd12003-01-07 20:57:09 +00007659 /* These come from sysexits.h */
7660#ifdef EX_OK
7661 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007662#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007663#ifdef EX_USAGE
7664 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007665#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007666#ifdef EX_DATAERR
7667 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007668#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007669#ifdef EX_NOINPUT
7670 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007671#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007672#ifdef EX_NOUSER
7673 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007674#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007675#ifdef EX_NOHOST
7676 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007677#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007678#ifdef EX_UNAVAILABLE
7679 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007680#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007681#ifdef EX_SOFTWARE
7682 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007683#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007684#ifdef EX_OSERR
7685 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007686#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007687#ifdef EX_OSFILE
7688 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007689#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007690#ifdef EX_CANTCREAT
7691 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007692#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007693#ifdef EX_IOERR
7694 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007695#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007696#ifdef EX_TEMPFAIL
7697 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007698#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007699#ifdef EX_PROTOCOL
7700 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007701#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007702#ifdef EX_NOPERM
7703 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007704#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007705#ifdef EX_CONFIG
7706 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007707#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007708#ifdef EX_NOTFOUND
7709 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007710#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007711
Guido van Rossum246bc171999-02-01 23:54:31 +00007712#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007713#if defined(PYOS_OS2) && defined(PYCC_GCC)
7714 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7715 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7716 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7717 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7718 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7719 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7720 if (ins(d, "P_PM", (long)P_PM)) return -1;
7721 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7722 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7723 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7724 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7725 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7726 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7727 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7728 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7729 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7730 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7731 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7732 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7733 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7734#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007735 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7736 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7737 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7738 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7739 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007740#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007741#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007742
Guido van Rossumd48f2521997-12-05 22:19:34 +00007743#if defined(PYOS_OS2)
7744 if (insertvalues(d)) return -1;
7745#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007746 return 0;
7747}
7748
7749
Tim Peters5aa91602002-01-30 05:46:57 +00007750#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007751#define INITFUNC initnt
7752#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007753
7754#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007755#define INITFUNC initos2
7756#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007757
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007758#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007759#define INITFUNC initposix
7760#define MODNAME "posix"
7761#endif
7762
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007763PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007764INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007765{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007766 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007767
Fred Drake4d1e64b2002-04-15 19:40:07 +00007768 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007769 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007770 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007771
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007772 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007773 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007774 Py_XINCREF(v);
7775 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007776 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007777 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007778
Fred Drake4d1e64b2002-04-15 19:40:07 +00007779 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007780 return;
7781
Fred Drake4d1e64b2002-04-15 19:40:07 +00007782 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007783 return;
7784
Fred Drake4d1e64b2002-04-15 19:40:07 +00007785 Py_INCREF(PyExc_OSError);
7786 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007787
Guido van Rossumb3d39562000-01-31 18:41:26 +00007788#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007789 if (posix_putenv_garbage == NULL)
7790 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007791#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007792
Guido van Rossum14648392001-12-08 18:02:58 +00007793 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007794 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7795 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7796 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007797 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007798 structseq_new = StatResultType.tp_new;
7799 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007800 Py_INCREF((PyObject*) &StatResultType);
7801 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007802
Guido van Rossum14648392001-12-08 18:02:58 +00007803 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007804 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007805 Py_INCREF((PyObject*) &StatVFSResultType);
7806 PyModule_AddObject(m, "statvfs_result",
7807 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007808}