boost/ocaml/python - all NON-WORKING at the moment.
[fedora-mingw.git] / python / mingw32-python-2.5.2-cross.patch
1 diff -urN Python-2.5.2.orig/configure.in Python-2.5.2.mingw/configure.in
2 --- Python-2.5.2.orig/configure.in      2008-10-06 18:43:25.000000000 +0100
3 +++ Python-2.5.2.mingw/configure.in     2008-10-07 11:54:04.000000000 +0100
4 @@ -9,6 +9,11 @@
5  AC_CONFIG_SRCDIR([Include/object.h])
6  AC_CONFIG_HEADER(pyconfig.h)
7  
8 +# Find compiler while respecting --host setting.
9 +AC_CANONICAL_HOST()
10 +AC_CHECK_TOOLS(CC,gcc cc)
11 +AC_CHECK_TOOLS(CXX,g++ c++)
12 +
13  dnl This is for stuff that absolutely must end up in pyconfig.h.
14  dnl Please use pyport.h instead, if possible.
15  AH_TOP([
16 @@ -165,6 +170,7 @@
17  AC_MSG_CHECKING(MACHDEP)
18  if test -z "$MACHDEP"
19  then
20 +    if test "$cross_compiling" = "no"; then
21         ac_sys_system=`uname -s`
22         if test "$ac_sys_system" = "AIX" -o "$ac_sys_system" = "Monterey64" \
23         -o "$ac_sys_system" = "UnixWare" -o "$ac_sys_system" = "OpenUNIX"; then
24 @@ -172,6 +178,21 @@
25         else
26                 ac_sys_release=`uname -r`
27         fi
28 +    else
29 +        m=`$CC -dumpmachine`
30 +       changequote(<<, >>)#dnl
31 +        ac_sys_system=`expr "$m" : "[^-]*-\([^-]*\)"`
32 +       changequote([, ])#dnl
33 +
34 +
35 +        case $ac_sys_system in
36 +        cygwin*) ac_sys_system=`echo $ac_sys_system | sed s/cygwin/CYGWIN/g `;;
37 +        darwin*) ac_sys_system=`echo $ac_sys_system | sed s/darwin/Darwin/g `;;
38 +        freebsd*) ac_sys_system=`echo $ac_sys_system | sed s/freebsd/FreeBSD/g `;;
39 +        linux*) ac_sys_system=`echo $ac_sys_system | sed s/linux/Linux/g `;;
40 +        esac
41 +    fi
42 +
43         ac_md_system=`echo $ac_sys_system |
44                            tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'`
45         ac_md_release=`echo $ac_sys_release |
46 @@ -434,7 +455,7 @@
47  fi
48  if test -z "$CXX"
49  then
50 -       AC_CHECK_PROGS(CXX, $CCC c++ g++ gcc CC cxx cc++ cl, notfound)
51 +       AC_CHECK_TOOLS(CXX, $CCC c++ g++ gcc CC cxx cc++ cl, notfound)
52         if test "$CXX" = "notfound"
53         then
54                 CXX=""
55 @@ -461,6 +482,7 @@
56     exit 1;;
57  esac
58  
59 +# The executable extension on the host.
60  AC_EXEEXT
61  AC_MSG_CHECKING(for --with-suffix)
62  AC_ARG_WITH(suffix,
63 @@ -491,6 +513,9 @@
64  fi
65  rmdir CaseSensitiveTestDir
66  
67 +# The .o/.obj extension on the host.
68 +AC_OBJEXT
69 +
70  case $MACHDEP in
71  bsdos*)
72      case $CC in
73 @@ -689,6 +714,8 @@
74  AC_PROG_RANLIB
75  AC_SUBST(AR)
76  AC_CHECK_PROGS(AR, ar aal, ar)
77 +AC_CHECK_TOOL(RANLIB,ranlib)
78 +AC_CHECK_TOOLS(AR,ar aal,ar)
79  
80  AC_SUBST(SVNVERSION)
81  AC_CHECK_PROG(SVNVERSION, svnversion, found, not-found)
82 @@ -3369,27 +3396,15 @@
83    AC_MSG_RESULT(no)
84  )
85  
86 -AC_MSG_CHECKING(for /dev/ptmx)
87 -
88 -if test -r /dev/ptmx
89 -then
90 -  AC_MSG_RESULT(yes)
91 -  AC_DEFINE(HAVE_DEV_PTMX, 1,
92 -  [Define if we have /dev/ptmx.])
93 -else
94 -  AC_MSG_RESULT(no)
95 -fi
96 -
97 -AC_MSG_CHECKING(for /dev/ptc)
98 -
99 -if test -r /dev/ptc
100 -then
101 -  AC_MSG_RESULT(yes)
102 -  AC_DEFINE(HAVE_DEV_PTC, 1,
103 -  [Define if we have /dev/ptc.])
104 -else
105 -  AC_MSG_RESULT(no)
106 -fi
107 +AC_CHECK_FILE(/dev/ptmx,
108 +       [AC_DEFINE(HAVE_DEV_PTMX, 1,
109 +          [Define if we have /dev/ptmx.])],
110 +       [])
111
112 +AC_CHECK_FILE(/dev/ptc,
113 +       [AC_DEFINE(HAVE_DEV_PTC, 1,
114 +          [Define if we have /dev/ptc.])],
115 +       [])
116  
117  case $MACHDEP in
118  darwin)        
119 @@ -3411,7 +3426,8 @@
120  
121  
122  AC_MSG_CHECKING(for %zd printf() format support)
123 -AC_TRY_RUN([#include <stdio.h>
124 +AC_CACHE_VAL(ac_cv_printf_zd_format,
125 +    AC_TRY_RUN([#include <stdio.h>
126  #include <stddef.h>
127  #include <string.h>
128  
129 @@ -3447,7 +3463,7 @@
130  }],
131  [AC_MSG_RESULT(yes)
132   AC_DEFINE(PY_FORMAT_SIZE_T, "z", [Define to printf format modifier for Py_ssize_t])],
133 - AC_MSG_RESULT(no))
134 + AC_MSG_RESULT(no)))
135  
136  AC_CHECK_TYPE(socklen_t,,
137    AC_DEFINE(socklen_t,int,
138 @@ -3477,6 +3493,53 @@
139  done
140  AC_MSG_RESULT(done)
141  
142 +# Cross compiling
143 +AC_SUBST(cross_compiling)
144 +
145 +if test "$cross_compiling" = "yes"; then
146 +    AC_MSG_CHECKING(cc for build)
147 +    CC_FOR_BUILD="${CC_FOR_BUILD-cc}"
148 +else
149 +    CC_FOR_BUILD="${CC_FOR_BUILD-$CC}"
150 +fi   
151 +     
152 +if test "$cross_compiling" = "yes"; then
153 +   AC_MSG_RESULT($CC_FOR_BUILD)
154 +fi
155 +
156 +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler (default: cc)])
157 +       
158 +if test "$cross_compiling" = "yes"; then
159 +    AC_MSG_CHECKING(python for build)
160 +    PYTHON_FOR_BUILD="${PYTHON_FOR_BUILD-python}"
161 +    PYTHON_FOR_BUILD=`which $PYTHON_FOR_BUILD`
162 +else
163 +    PYTHON_FOR_BUILD='./$(BUILDPYTHON)'
164 +fi   
165 +
166 +if test "$cross_compiling" = "yes"; then
167 +    AC_MSG_RESULT($PYTHON_FOR_BUILD)
168 +fi
169 +AC_ARG_VAR(PYTHON_FOR_BUILD,[build system python (default: python)])
170 +AC_SUBST(PYTHON_FOR_BUILD)
171 +
172 +if test "$cross_compiling" = "yes"; then
173 +    CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-}
174 +    CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD- -I.}
175 +    CROSS_COMMENT=#
176 +    LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-}
177 +    O_FOR_BUILD=x
178 +    RUNSHARED="MACHDEP=$ac_sys_system SRCDIR=$srcdir SO=${SO}"
179 +else
180 +    CROSS_COMMENT=
181 +    O_FOR_BUILD=$(OBJEXT)
182 +fi
183 +AC_SUBST(CFLAGS_FOR_BUILD)
184 +AC_SUBST(CPPFLAGS_FOR_BUILD)
185 +AC_SUBST(CROSS_COMMENT)
186 +AC_SUBST(LDFLAGS_FOR_BUILD)
187 +AC_SUBST(O_FOR_BUILD)
188 +
189  # generate output files
190  AC_CONFIG_FILES(Makefile.pre Modules/Setup.config)
191  AC_OUTPUT
192 diff -urN Python-2.5.2.orig/Lib/distutils/command/build_ext.py Python-2.5.2.mingw/Lib/distutils/command/build_ext.py
193 --- Python-2.5.2.orig/Lib/distutils/command/build_ext.py        2007-04-24 16:27:25.000000000 +0100
194 +++ Python-2.5.2.mingw/Lib/distutils/command/build_ext.py       2008-10-06 19:22:51.000000000 +0100
195 @@ -624,6 +624,8 @@
196              ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
197          # extensions in debug_mode are named 'module_d.pyd' under windows
198          so_ext = get_config_var('SO')
199 +        if os.environ.get('CROSS_COMPILING') == 'yes':
200 +            so_ext = os.environ.get('SO')
201          if os.name == 'nt' and self.debug:
202              return apply(os.path.join, ext_path) + '_d' + so_ext
203          return apply(os.path.join, ext_path) + so_ext
204 @@ -705,6 +707,8 @@
205              return ext.libraries
206  
207          else:
208 +            if os.environ.get('CROSS_COMPILING') == 'yes':
209 +                return []
210              from distutils import sysconfig
211              if sysconfig.get_config_var('Py_ENABLE_SHARED'):
212                  template = "python%d.%d"
213 diff -urN Python-2.5.2.orig/Lib/distutils/command/build_ext.py~ Python-2.5.2.mingw/Lib/distutils/command/build_ext.py~
214 --- Python-2.5.2.orig/Lib/distutils/command/build_ext.py~       1970-01-01 01:00:00.000000000 +0100
215 +++ Python-2.5.2.mingw/Lib/distutils/command/build_ext.py~      2007-04-24 16:27:25.000000000 +0100
216 @@ -0,0 +1,717 @@
217 +"""distutils.command.build_ext
218 +
219 +Implements the Distutils 'build_ext' command, for building extension
220 +modules (currently limited to C extensions, should accommodate C++
221 +extensions ASAP)."""
222 +
223 +# This module should be kept compatible with Python 2.1.
224 +
225 +__revision__ = "$Id: build_ext.py 54942 2007-04-24 15:27:25Z georg.brandl $"
226 +
227 +import sys, os, string, re
228 +from types import *
229 +from distutils.core import Command
230 +from distutils.errors import *
231 +from distutils.sysconfig import customize_compiler, get_python_version
232 +from distutils.dep_util import newer_group
233 +from distutils.extension import Extension
234 +from distutils import log
235 +
236 +# An extension name is just a dot-separated list of Python NAMEs (ie.
237 +# the same as a fully-qualified module name).
238 +extension_name_re = re.compile \
239 +    (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
240 +
241 +
242 +def show_compilers ():
243 +    from distutils.ccompiler import show_compilers
244 +    show_compilers()
245 +
246 +
247 +class build_ext (Command):
248 +
249 +    description = "build C/C++ extensions (compile/link to build directory)"
250 +
251 +    # XXX thoughts on how to deal with complex command-line options like
252 +    # these, i.e. how to make it so fancy_getopt can suck them off the
253 +    # command line and make it look like setup.py defined the appropriate
254 +    # lists of tuples of what-have-you.
255 +    #   - each command needs a callback to process its command-line options
256 +    #   - Command.__init__() needs access to its share of the whole
257 +    #     command line (must ultimately come from
258 +    #     Distribution.parse_command_line())
259 +    #   - it then calls the current command class' option-parsing
260 +    #     callback to deal with weird options like -D, which have to
261 +    #     parse the option text and churn out some custom data
262 +    #     structure
263 +    #   - that data structure (in this case, a list of 2-tuples)
264 +    #     will then be present in the command object by the time
265 +    #     we get to finalize_options() (i.e. the constructor
266 +    #     takes care of both command-line and client options
267 +    #     in between initialize_options() and finalize_options())
268 +
269 +    sep_by = " (separated by '%s')" % os.pathsep
270 +    user_options = [
271 +        ('build-lib=', 'b',
272 +         "directory for compiled extension modules"),
273 +        ('build-temp=', 't',
274 +         "directory for temporary files (build by-products)"),
275 +        ('inplace', 'i',
276 +         "ignore build-lib and put compiled extensions into the source " +
277 +         "directory alongside your pure Python modules"),
278 +        ('include-dirs=', 'I',
279 +         "list of directories to search for header files" + sep_by),
280 +        ('define=', 'D',
281 +         "C preprocessor macros to define"),
282 +        ('undef=', 'U',
283 +         "C preprocessor macros to undefine"),
284 +        ('libraries=', 'l',
285 +         "external C libraries to link with"),
286 +        ('library-dirs=', 'L',
287 +         "directories to search for external C libraries" + sep_by),
288 +        ('rpath=', 'R',
289 +         "directories to search for shared C libraries at runtime"),
290 +        ('link-objects=', 'O',
291 +         "extra explicit link objects to include in the link"),
292 +        ('debug', 'g',
293 +         "compile/link with debugging information"),
294 +        ('force', 'f',
295 +         "forcibly build everything (ignore file timestamps)"),
296 +        ('compiler=', 'c',
297 +         "specify the compiler type"),
298 +        ('swig-cpp', None,
299 +         "make SWIG create C++ files (default is C)"),
300 +        ('swig-opts=', None,
301 +         "list of SWIG command line options"),
302 +        ('swig=', None,
303 +         "path to the SWIG executable"),
304 +        ]
305 +
306 +    boolean_options = ['inplace', 'debug', 'force', 'swig-cpp']
307 +
308 +    help_options = [
309 +        ('help-compiler', None,
310 +         "list available compilers", show_compilers),
311 +        ]
312 +
313 +    def initialize_options (self):
314 +        self.extensions = None
315 +        self.build_lib = None
316 +        self.build_temp = None
317 +        self.inplace = 0
318 +        self.package = None
319 +
320 +        self.include_dirs = None
321 +        self.define = None
322 +        self.undef = None
323 +        self.libraries = None
324 +        self.library_dirs = None
325 +        self.rpath = None
326 +        self.link_objects = None
327 +        self.debug = None
328 +        self.force = None
329 +        self.compiler = None
330 +        self.swig = None
331 +        self.swig_cpp = None
332 +        self.swig_opts = None
333 +
334 +    def finalize_options (self):
335 +        from distutils import sysconfig
336 +
337 +        self.set_undefined_options('build',
338 +                                   ('build_lib', 'build_lib'),
339 +                                   ('build_temp', 'build_temp'),
340 +                                   ('compiler', 'compiler'),
341 +                                   ('debug', 'debug'),
342 +                                   ('force', 'force'))
343 +
344 +        if self.package is None:
345 +            self.package = self.distribution.ext_package
346 +
347 +        self.extensions = self.distribution.ext_modules
348 +
349 +
350 +        # Make sure Python's include directories (for Python.h, pyconfig.h,
351 +        # etc.) are in the include search path.
352 +        py_include = sysconfig.get_python_inc()
353 +        plat_py_include = sysconfig.get_python_inc(plat_specific=1)
354 +        if self.include_dirs is None:
355 +            self.include_dirs = self.distribution.include_dirs or []
356 +        if type(self.include_dirs) is StringType:
357 +            self.include_dirs = string.split(self.include_dirs, os.pathsep)
358 +
359 +        # Put the Python "system" include dir at the end, so that
360 +        # any local include dirs take precedence.
361 +        self.include_dirs.append(py_include)
362 +        if plat_py_include != py_include:
363 +            self.include_dirs.append(plat_py_include)
364 +
365 +        if type(self.libraries) is StringType:
366 +            self.libraries = [self.libraries]
367 +
368 +        # Life is easier if we're not forever checking for None, so
369 +        # simplify these options to empty lists if unset
370 +        if self.libraries is None:
371 +            self.libraries = []
372 +        if self.library_dirs is None:
373 +            self.library_dirs = []
374 +        elif type(self.library_dirs) is StringType:
375 +            self.library_dirs = string.split(self.library_dirs, os.pathsep)
376 +
377 +        if self.rpath is None:
378 +            self.rpath = []
379 +        elif type(self.rpath) is StringType:
380 +            self.rpath = string.split(self.rpath, os.pathsep)
381 +
382 +        # for extensions under windows use different directories
383 +        # for Release and Debug builds.
384 +        # also Python's library directory must be appended to library_dirs
385 +        if os.name == 'nt':
386 +            self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
387 +            if self.debug:
388 +                self.build_temp = os.path.join(self.build_temp, "Debug")
389 +            else:
390 +                self.build_temp = os.path.join(self.build_temp, "Release")
391 +
392 +            # Append the source distribution include and library directories,
393 +            # this allows distutils on windows to work in the source tree
394 +            self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
395 +            self.library_dirs.append(os.path.join(sys.exec_prefix, 'PCBuild'))
396 +
397 +        # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
398 +        # import libraries in its "Config" subdirectory
399 +        if os.name == 'os2':
400 +            self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config'))
401 +
402 +        # for extensions under Cygwin and AtheOS Python's library directory must be
403 +        # appended to library_dirs
404 +        if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos':
405 +            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
406 +                # building third party extensions
407 +                self.library_dirs.append(os.path.join(sys.prefix, "lib",
408 +                                                      "python" + get_python_version(),
409 +                                                      "config"))
410 +            else:
411 +                # building python standard extensions
412 +                self.library_dirs.append('.')
413 +
414 +        # for extensions under Linux with a shared Python library,
415 +        # Python's library directory must be appended to library_dirs
416 +        if (sys.platform.startswith('linux') or sys.platform.startswith('gnu')) \
417 +                and sysconfig.get_config_var('Py_ENABLE_SHARED'):
418 +            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
419 +                # building third party extensions
420 +                self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
421 +            else:
422 +                # building python standard extensions
423 +                self.library_dirs.append('.')
424 +
425 +        # The argument parsing will result in self.define being a string, but
426 +        # it has to be a list of 2-tuples.  All the preprocessor symbols
427 +        # specified by the 'define' option will be set to '1'.  Multiple
428 +        # symbols can be separated with commas.
429 +
430 +        if self.define:
431 +            defines = string.split(self.define, ',')
432 +            self.define = map(lambda symbol: (symbol, '1'), defines)
433 +
434 +        # The option for macros to undefine is also a string from the
435 +        # option parsing, but has to be a list.  Multiple symbols can also
436 +        # be separated with commas here.
437 +        if self.undef:
438 +            self.undef = string.split(self.undef, ',')
439 +
440 +        if self.swig_opts is None:
441 +            self.swig_opts = []
442 +        else:
443 +            self.swig_opts = self.swig_opts.split(' ')
444 +
445 +    # finalize_options ()
446 +
447 +
448 +    def run (self):
449 +
450 +        from distutils.ccompiler import new_compiler
451 +
452 +        # 'self.extensions', as supplied by setup.py, is a list of
453 +        # Extension instances.  See the documentation for Extension (in
454 +        # distutils.extension) for details.
455 +        #
456 +        # For backwards compatibility with Distutils 0.8.2 and earlier, we
457 +        # also allow the 'extensions' list to be a list of tuples:
458 +        #    (ext_name, build_info)
459 +        # where build_info is a dictionary containing everything that
460 +        # Extension instances do except the name, with a few things being
461 +        # differently named.  We convert these 2-tuples to Extension
462 +        # instances as needed.
463 +
464 +        if not self.extensions:
465 +            return
466 +
467 +        # If we were asked to build any C/C++ libraries, make sure that the
468 +        # directory where we put them is in the library search path for
469 +        # linking extensions.
470 +        if self.distribution.has_c_libraries():
471 +            build_clib = self.get_finalized_command('build_clib')
472 +            self.libraries.extend(build_clib.get_library_names() or [])
473 +            self.library_dirs.append(build_clib.build_clib)
474 +
475 +        # Setup the CCompiler object that we'll use to do all the
476 +        # compiling and linking
477 +        self.compiler = new_compiler(compiler=self.compiler,
478 +                                     verbose=self.verbose,
479 +                                     dry_run=self.dry_run,
480 +                                     force=self.force)
481 +        customize_compiler(self.compiler)
482 +
483 +        # And make sure that any compile/link-related options (which might
484 +        # come from the command-line or from the setup script) are set in
485 +        # that CCompiler object -- that way, they automatically apply to
486 +        # all compiling and linking done here.
487 +        if self.include_dirs is not None:
488 +            self.compiler.set_include_dirs(self.include_dirs)
489 +        if self.define is not None:
490 +            # 'define' option is a list of (name,value) tuples
491 +            for (name,value) in self.define:
492 +                self.compiler.define_macro(name, value)
493 +        if self.undef is not None:
494 +            for macro in self.undef:
495 +                self.compiler.undefine_macro(macro)
496 +        if self.libraries is not None:
497 +            self.compiler.set_libraries(self.libraries)
498 +        if self.library_dirs is not None:
499 +            self.compiler.set_library_dirs(self.library_dirs)
500 +        if self.rpath is not None:
501 +            self.compiler.set_runtime_library_dirs(self.rpath)
502 +        if self.link_objects is not None:
503 +            self.compiler.set_link_objects(self.link_objects)
504 +
505 +        # Now actually compile and link everything.
506 +        self.build_extensions()
507 +
508 +    # run ()
509 +
510 +
511 +    def check_extensions_list (self, extensions):
512 +        """Ensure that the list of extensions (presumably provided as a
513 +        command option 'extensions') is valid, i.e. it is a list of
514 +        Extension objects.  We also support the old-style list of 2-tuples,
515 +        where the tuples are (ext_name, build_info), which are converted to
516 +        Extension instances here.
517 +
518 +        Raise DistutilsSetupError if the structure is invalid anywhere;
519 +        just returns otherwise.
520 +        """
521 +        if type(extensions) is not ListType:
522 +            raise DistutilsSetupError, \
523 +                  "'ext_modules' option must be a list of Extension instances"
524 +
525 +        for i in range(len(extensions)):
526 +            ext = extensions[i]
527 +            if isinstance(ext, Extension):
528 +                continue                # OK! (assume type-checking done
529 +                                        # by Extension constructor)
530 +
531 +            (ext_name, build_info) = ext
532 +            log.warn(("old-style (ext_name, build_info) tuple found in "
533 +                      "ext_modules for extension '%s'"
534 +                      "-- please convert to Extension instance" % ext_name))
535 +            if type(ext) is not TupleType and len(ext) != 2:
536 +                raise DistutilsSetupError, \
537 +                      ("each element of 'ext_modules' option must be an "
538 +                       "Extension instance or 2-tuple")
539 +
540 +            if not (type(ext_name) is StringType and
541 +                    extension_name_re.match(ext_name)):
542 +                raise DistutilsSetupError, \
543 +                      ("first element of each tuple in 'ext_modules' "
544 +                       "must be the extension name (a string)")
545 +
546 +            if type(build_info) is not DictionaryType:
547 +                raise DistutilsSetupError, \
548 +                      ("second element of each tuple in 'ext_modules' "
549 +                       "must be a dictionary (build info)")
550 +
551 +            # OK, the (ext_name, build_info) dict is type-safe: convert it
552 +            # to an Extension instance.
553 +            ext = Extension(ext_name, build_info['sources'])
554 +
555 +            # Easy stuff: one-to-one mapping from dict elements to
556 +            # instance attributes.
557 +            for key in ('include_dirs',
558 +                        'library_dirs',
559 +                        'libraries',
560 +                        'extra_objects',
561 +                        'extra_compile_args',
562 +                        'extra_link_args'):
563 +                val = build_info.get(key)
564 +                if val is not None:
565 +                    setattr(ext, key, val)
566 +
567 +            # Medium-easy stuff: same syntax/semantics, different names.
568 +            ext.runtime_library_dirs = build_info.get('rpath')
569 +            if build_info.has_key('def_file'):
570 +                log.warn("'def_file' element of build info dict "
571 +                         "no longer supported")
572 +
573 +            # Non-trivial stuff: 'macros' split into 'define_macros'
574 +            # and 'undef_macros'.
575 +            macros = build_info.get('macros')
576 +            if macros:
577 +                ext.define_macros = []
578 +                ext.undef_macros = []
579 +                for macro in macros:
580 +                    if not (type(macro) is TupleType and
581 +                            1 <= len(macro) <= 2):
582 +                        raise DistutilsSetupError, \
583 +                              ("'macros' element of build info dict "
584 +                               "must be 1- or 2-tuple")
585 +                    if len(macro) == 1:
586 +                        ext.undef_macros.append(macro[0])
587 +                    elif len(macro) == 2:
588 +                        ext.define_macros.append(macro)
589 +
590 +            extensions[i] = ext
591 +
592 +        # for extensions
593 +
594 +    # check_extensions_list ()
595 +
596 +
597 +    def get_source_files (self):
598 +        self.check_extensions_list(self.extensions)
599 +        filenames = []
600 +
601 +        # Wouldn't it be neat if we knew the names of header files too...
602 +        for ext in self.extensions:
603 +            filenames.extend(ext.sources)
604 +
605 +        return filenames
606 +
607 +
608 +    def get_outputs (self):
609 +
610 +        # Sanity check the 'extensions' list -- can't assume this is being
611 +        # done in the same run as a 'build_extensions()' call (in fact, we
612 +        # can probably assume that it *isn't*!).
613 +        self.check_extensions_list(self.extensions)
614 +
615 +        # And build the list of output (built) filenames.  Note that this
616 +        # ignores the 'inplace' flag, and assumes everything goes in the
617 +        # "build" tree.
618 +        outputs = []
619 +        for ext in self.extensions:
620 +            fullname = self.get_ext_fullname(ext.name)
621 +            outputs.append(os.path.join(self.build_lib,
622 +                                        self.get_ext_filename(fullname)))
623 +        return outputs
624 +
625 +    # get_outputs ()
626 +
627 +    def build_extensions(self):
628 +        # First, sanity-check the 'extensions' list
629 +        self.check_extensions_list(self.extensions)
630 +
631 +        for ext in self.extensions:
632 +            self.build_extension(ext)
633 +
634 +    def build_extension(self, ext):
635 +        sources = ext.sources
636 +        if sources is None or type(sources) not in (ListType, TupleType):
637 +            raise DistutilsSetupError, \
638 +                  ("in 'ext_modules' option (extension '%s'), " +
639 +                   "'sources' must be present and must be " +
640 +                   "a list of source filenames") % ext.name
641 +        sources = list(sources)
642 +
643 +        fullname = self.get_ext_fullname(ext.name)
644 +        if self.inplace:
645 +            # ignore build-lib -- put the compiled extension into
646 +            # the source tree along with pure Python modules
647 +
648 +            modpath = string.split(fullname, '.')
649 +            package = string.join(modpath[0:-1], '.')
650 +            base = modpath[-1]
651 +
652 +            build_py = self.get_finalized_command('build_py')
653 +            package_dir = build_py.get_package_dir(package)
654 +            ext_filename = os.path.join(package_dir,
655 +                                        self.get_ext_filename(base))
656 +        else:
657 +            ext_filename = os.path.join(self.build_lib,
658 +                                        self.get_ext_filename(fullname))
659 +        depends = sources + ext.depends
660 +        if not (self.force or newer_group(depends, ext_filename, 'newer')):
661 +            log.debug("skipping '%s' extension (up-to-date)", ext.name)
662 +            return
663 +        else:
664 +            log.info("building '%s' extension", ext.name)
665 +
666 +        # First, scan the sources for SWIG definition files (.i), run
667 +        # SWIG on 'em to create .c files, and modify the sources list
668 +        # accordingly.
669 +        sources = self.swig_sources(sources, ext)
670 +
671 +        # Next, compile the source code to object files.
672 +
673 +        # XXX not honouring 'define_macros' or 'undef_macros' -- the
674 +        # CCompiler API needs to change to accommodate this, and I
675 +        # want to do one thing at a time!
676 +
677 +        # Two possible sources for extra compiler arguments:
678 +        #   - 'extra_compile_args' in Extension object
679 +        #   - CFLAGS environment variable (not particularly
680 +        #     elegant, but people seem to expect it and I
681 +        #     guess it's useful)
682 +        # The environment variable should take precedence, and
683 +        # any sensible compiler will give precedence to later
684 +        # command line args.  Hence we combine them in order:
685 +        extra_args = ext.extra_compile_args or []
686 +
687 +        macros = ext.define_macros[:]
688 +        for undef in ext.undef_macros:
689 +            macros.append((undef,))
690 +
691 +        objects = self.compiler.compile(sources,
692 +                                        output_dir=self.build_temp,
693 +                                        macros=macros,
694 +                                        include_dirs=ext.include_dirs,
695 +                                        debug=self.debug,
696 +                                        extra_postargs=extra_args,
697 +                                        depends=ext.depends)
698 +
699 +        # XXX -- this is a Vile HACK!
700 +        #
701 +        # The setup.py script for Python on Unix needs to be able to
702 +        # get this list so it can perform all the clean up needed to
703 +        # avoid keeping object files around when cleaning out a failed
704 +        # build of an extension module.  Since Distutils does not
705 +        # track dependencies, we have to get rid of intermediates to
706 +        # ensure all the intermediates will be properly re-built.
707 +        #
708 +        self._built_objects = objects[:]
709 +
710 +        # Now link the object files together into a "shared object" --
711 +        # of course, first we have to figure out all the other things
712 +        # that go into the mix.
713 +        if ext.extra_objects:
714 +            objects.extend(ext.extra_objects)
715 +        extra_args = ext.extra_link_args or []
716 +
717 +        # Detect target language, if not provided
718 +        language = ext.language or self.compiler.detect_language(sources)
719 +
720 +        self.compiler.link_shared_object(
721 +            objects, ext_filename,
722 +            libraries=self.get_libraries(ext),
723 +            library_dirs=ext.library_dirs,
724 +            runtime_library_dirs=ext.runtime_library_dirs,
725 +            extra_postargs=extra_args,
726 +            export_symbols=self.get_export_symbols(ext),
727 +            debug=self.debug,
728 +            build_temp=self.build_temp,
729 +            target_lang=language)
730 +
731 +
732 +    def swig_sources (self, sources, extension):
733 +
734 +        """Walk the list of source files in 'sources', looking for SWIG
735 +        interface (.i) files.  Run SWIG on all that are found, and
736 +        return a modified 'sources' list with SWIG source files replaced
737 +        by the generated C (or C++) files.
738 +        """
739 +
740 +        new_sources = []
741 +        swig_sources = []
742 +        swig_targets = {}
743 +
744 +        # XXX this drops generated C/C++ files into the source tree, which
745 +        # is fine for developers who want to distribute the generated
746 +        # source -- but there should be an option to put SWIG output in
747 +        # the temp dir.
748 +
749 +        if self.swig_cpp:
750 +            log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
751 +
752 +        if self.swig_cpp or ('-c++' in self.swig_opts) or \
753 +           ('-c++' in extension.swig_opts):
754 +            target_ext = '.cpp'
755 +        else:
756 +            target_ext = '.c'
757 +
758 +        for source in sources:
759 +            (base, ext) = os.path.splitext(source)
760 +            if ext == ".i":             # SWIG interface file
761 +                new_sources.append(base + '_wrap' + target_ext)
762 +                swig_sources.append(source)
763 +                swig_targets[source] = new_sources[-1]
764 +            else:
765 +                new_sources.append(source)
766 +
767 +        if not swig_sources:
768 +            return new_sources
769 +
770 +        swig = self.swig or self.find_swig()
771 +        swig_cmd = [swig, "-python"]
772 +        swig_cmd.extend(self.swig_opts)
773 +        if self.swig_cpp:
774 +            swig_cmd.append("-c++")
775 +
776 +        # Do not override commandline arguments
777 +        if not self.swig_opts:
778 +            for o in extension.swig_opts:
779 +                swig_cmd.append(o)
780 +
781 +        for source in swig_sources:
782 +            target = swig_targets[source]
783 +            log.info("swigging %s to %s", source, target)
784 +            self.spawn(swig_cmd + ["-o", target, source])
785 +
786 +        return new_sources
787 +
788 +    # swig_sources ()
789 +
790 +    def find_swig (self):
791 +        """Return the name of the SWIG executable.  On Unix, this is
792 +        just "swig" -- it should be in the PATH.  Tries a bit harder on
793 +        Windows.
794 +        """
795 +
796 +        if os.name == "posix":
797 +            return "swig"
798 +        elif os.name == "nt":
799 +
800 +            # Look for SWIG in its standard installation directory on
801 +            # Windows (or so I presume!).  If we find it there, great;
802 +            # if not, act like Unix and assume it's in the PATH.
803 +            for vers in ("1.3", "1.2", "1.1"):
804 +                fn = os.path.join("c:\\swig%s" % vers, "swig.exe")
805 +                if os.path.isfile(fn):
806 +                    return fn
807 +            else:
808 +                return "swig.exe"
809 +
810 +        elif os.name == "os2":
811 +            # assume swig available in the PATH.
812 +            return "swig.exe"
813 +
814 +        else:
815 +            raise DistutilsPlatformError, \
816 +                  ("I don't know how to find (much less run) SWIG "
817 +                   "on platform '%s'") % os.name
818 +
819 +    # find_swig ()
820 +
821 +    # -- Name generators -----------------------------------------------
822 +    # (extension names, filenames, whatever)
823 +
824 +    def get_ext_fullname (self, ext_name):
825 +        if self.package is None:
826 +            return ext_name
827 +        else:
828 +            return self.package + '.' + ext_name
829 +
830 +    def get_ext_filename (self, ext_name):
831 +        r"""Convert the name of an extension (eg. "foo.bar") into the name
832 +        of the file from which it will be loaded (eg. "foo/bar.so", or
833 +        "foo\bar.pyd").
834 +        """
835 +
836 +        from distutils.sysconfig import get_config_var
837 +        ext_path = string.split(ext_name, '.')
838 +        # OS/2 has an 8 character module (extension) limit :-(
839 +        if os.name == "os2":
840 +            ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
841 +        # extensions in debug_mode are named 'module_d.pyd' under windows
842 +        so_ext = get_config_var('SO')
843 +        if os.name == 'nt' and self.debug:
844 +            return apply(os.path.join, ext_path) + '_d' + so_ext
845 +        return apply(os.path.join, ext_path) + so_ext
846 +
847 +    def get_export_symbols (self, ext):
848 +        """Return the list of symbols that a shared extension has to
849 +        export.  This either uses 'ext.export_symbols' or, if it's not
850 +        provided, "init" + module_name.  Only relevant on Windows, where
851 +        the .pyd file (DLL) must export the module "init" function.
852 +        """
853 +
854 +        initfunc_name = "init" + string.split(ext.name,'.')[-1]
855 +        if initfunc_name not in ext.export_symbols:
856 +            ext.export_symbols.append(initfunc_name)
857 +        return ext.export_symbols
858 +
859 +    def get_libraries (self, ext):
860 +        """Return the list of libraries to link against when building a
861 +        shared extension.  On most platforms, this is just 'ext.libraries';
862 +        on Windows and OS/2, we add the Python library (eg. python20.dll).
863 +        """
864 +        # The python library is always needed on Windows.  For MSVC, this
865 +        # is redundant, since the library is mentioned in a pragma in
866 +        # pyconfig.h that MSVC groks.  The other Windows compilers all seem
867 +        # to need it mentioned explicitly, though, so that's what we do.
868 +        # Append '_d' to the python import library on debug builds.
869 +        if sys.platform == "win32":
870 +            from distutils.msvccompiler import MSVCCompiler
871 +            if not isinstance(self.compiler, MSVCCompiler):
872 +                template = "python%d%d"
873 +                if self.debug:
874 +                    template = template + '_d'
875 +                pythonlib = (template %
876 +                       (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
877 +                # don't extend ext.libraries, it may be shared with other
878 +                # extensions, it is a reference to the original list
879 +                return ext.libraries + [pythonlib]
880 +            else:
881 +                return ext.libraries
882 +        elif sys.platform == "os2emx":
883 +            # EMX/GCC requires the python library explicitly, and I
884 +            # believe VACPP does as well (though not confirmed) - AIM Apr01
885 +            template = "python%d%d"
886 +            # debug versions of the main DLL aren't supported, at least
887 +            # not at this time - AIM Apr01
888 +            #if self.debug:
889 +            #    template = template + '_d'
890 +            pythonlib = (template %
891 +                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
892 +            # don't extend ext.libraries, it may be shared with other
893 +            # extensions, it is a reference to the original list
894 +            return ext.libraries + [pythonlib]
895 +        elif sys.platform[:6] == "cygwin":
896 +            template = "python%d.%d"
897 +            pythonlib = (template %
898 +                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
899 +            # don't extend ext.libraries, it may be shared with other
900 +            # extensions, it is a reference to the original list
901 +            return ext.libraries + [pythonlib]
902 +        elif sys.platform[:6] == "atheos":
903 +            from distutils import sysconfig
904 +
905 +            template = "python%d.%d"
906 +            pythonlib = (template %
907 +                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
908 +            # Get SHLIBS from Makefile
909 +            extra = []
910 +            for lib in sysconfig.get_config_var('SHLIBS').split():
911 +                if lib.startswith('-l'):
912 +                    extra.append(lib[2:])
913 +                else:
914 +                    extra.append(lib)
915 +            # don't extend ext.libraries, it may be shared with other
916 +            # extensions, it is a reference to the original list
917 +            return ext.libraries + [pythonlib, "m"] + extra
918 +
919 +        elif sys.platform == 'darwin':
920 +            # Don't use the default code below
921 +            return ext.libraries
922 +
923 +        else:
924 +            from distutils import sysconfig
925 +            if sysconfig.get_config_var('Py_ENABLE_SHARED'):
926 +                template = "python%d.%d"
927 +                pythonlib = (template %
928 +                             (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
929 +                return ext.libraries + [pythonlib]
930 +            else:
931 +                return ext.libraries
932 +
933 +# class build_ext
934 diff -urN Python-2.5.2.orig/Makefile.pre.in Python-2.5.2.mingw/Makefile.pre.in
935 --- Python-2.5.2.orig/Makefile.pre.in   2008-10-06 18:43:25.000000000 +0100
936 +++ Python-2.5.2.mingw/Makefile.pre.in  2008-10-07 11:56:31.000000000 +0100
937 @@ -27,6 +27,7 @@
938  VERSION=       @VERSION@
939  srcdir=                @srcdir@
940  VPATH=         @srcdir@
941 +export         srcdir
942  
943  CC=            @CC@
944  CXX=           @CXX@
945 @@ -72,6 +73,18 @@
946  # C flags used for building the interpreter object files
947  PY_CFLAGS=     $(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
948  
949 +# For cross compiling, *_FOR_BUILD are compiler/flags for the
950 +# build compiler (ie. for making intermediate tools).
951 +CC_FOR_BUILD=  @CC_FOR_BUILD@
952 +CROSS_COMPILING=       @cross_compiling@
953 +EXEEXT=                       @EXEEXT@
954 +
955 +CFLAGS_FOR_BUILD=      @CFLAGS_FOR_BUILD@
956 +CPPFLAGS_FOR_BUILD=    @CPPFLAGS_FOR_BUILD@ -I$(srcdir)/Include
957 +LDFLAGS_FOR_BUILD=     @LDFLAGS_FOR_BUILD@
958 +O_FOR_BUILD=          @O_FOR_BUILD@
959 +
960 +PYTHON_FOR_BUILD=      @PYTHON_FOR_BUILD@
961  
962  # Machine-dependent subdirectories
963  MACHDEP=       @MACHDEP@
964 @@ -201,26 +214,28 @@
965  PGEN=          Parser/pgen$(EXE)
966  
967  POBJS=         \
968 -               Parser/acceler.o \
969 -               Parser/grammar1.o \
970 -               Parser/listnode.o \
971 -               Parser/node.o \
972 -               Parser/parser.o \
973 -               Parser/parsetok.o \
974 -               Parser/bitset.o \
975 -               Parser/metagrammar.o \
976 -               Parser/firstsets.o \
977 -               Parser/grammar.o \
978 -               Parser/pgen.o
979 -
980 -PARSER_OBJS=   $(POBJS) Parser/myreadline.o Parser/tokenizer.o
981 +               Parser/acceler.$(O_FOR_BUILD) \
982 +               Parser/grammar1.$(O_FOR_BUILD) \
983 +               Parser/listnode.$(O_FOR_BUILD) \
984 +               Parser/node.$(O_FOR_BUILD) \
985 +               Parser/parser.$(O_FOR_BUILD) \
986 +               Parser/parsetok.$(O_FOR_BUILD) \
987 +               Parser/bitset.$(O_FOR_BUILD) \
988 +               Parser/metagrammar.$(O_FOR_BUILD) \
989 +               Parser/firstsets.$(O_FOR_BUILD) \
990 +               Parser/grammar.$(O_FOR_BUILD) \
991 +               Parser/pgen.$(O_FOR_BUILD)
992 +
993 +PARSER_OBJS=   $(POBJS) \
994 +               Parser/myreadline.$(O_FOR_BUILD) \
995 +               Parser/tokenizer.$(O_FOR_BUILD)
996  
997  PGOBJS=                \
998 -               Objects/obmalloc.o \
999 -               Python/mysnprintf.o \
1000 -               Parser/tokenizer_pgen.o \
1001 -               Parser/printgrammar.o \
1002 -               Parser/pgenmain.o
1003 +               Objects/obmalloc.$(O_FOR_BUILD) \
1004 +               Python/mysnprintf.$(O_FOR_BUILD) \
1005 +               Parser/tokenizer_pgen.$(O_FOR_BUILD) \
1006 +               Parser/printgrammar.$(O_FOR_BUILD) \
1007 +               Parser/pgenmain.$(O_FOR_BUILD)
1008  
1009  PGENOBJS=      $(PGENMAIN) $(POBJS) $(PGOBJS)
1010  
1011 @@ -341,15 +356,15 @@
1012                         Modules/python.o \
1013                         $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
1014  
1015 -platform: $(BUILDPYTHON)
1016 -       $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
1017 +platform: $(PYTHON_FOR_BUILD)
1018 +       $(RUNSHARED) ./$(PYTHON_FOR_BUILD) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
1019  
1020  
1021  # Build the shared modules
1022 -sharedmods: $(BUILDPYTHON)
1023 +sharedmods: $(PYTHON_FOR_BUILD)
1024         case $$MAKEFLAGS in \
1025 -       *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
1026 -       *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
1027 +       *-s*) $(RUNSHARED) CROSS_COMPILING=$(CROSS_COMPILING) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' $(PYTHON_FOR_BUILD) -E $(srcdir)/setup.py -q build;; \
1028 +       *) $(RUNSHARED) CROSS_COMPILING=$(CROSS_COMPILING) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' $(PYTHON_FOR_BUILD) -E $(srcdir)/setup.py build;; \
1029         esac
1030  
1031  # Build static library
1032 @@ -477,7 +492,7 @@
1033                 -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
1034  
1035  $(PGEN):       $(PGENOBJS)
1036 -               $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
1037 +               $(CC_FOR_BUILD) $(OPT) $(LDFLAGS_FOR_BUILD) $(PGENOBJS) $(LIBS) -o $(PGEN)
1038  
1039  Parser/grammar.o:      $(srcdir)/Parser/grammar.c \
1040                                 $(srcdir)/Include/token.h \
1041 @@ -576,7 +591,7 @@
1042  
1043  TESTOPTS=      -l $(EXTRATESTOPTS)
1044  TESTPROG=      $(srcdir)/Lib/test/regrtest.py
1045 -TESTPYTHON=    $(RUNSHARED) ./$(BUILDPYTHON) -E -tt
1046 +TESTPYTHON=    $(RUNSHARED) $(PYTHON_FOR_BUILD) -E -tt
1047  test:          all platform
1048                 -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1049                 -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
1050 @@ -597,7 +612,7 @@
1051                 -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1052                 -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1053                 $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1054 -               $(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
1055 +               $(RUNSHARED) /usr/libexec/oah/translate $(PYTHON_FOR_BUILD) -E -tt $(TESTPROG) $(TESTOPTS) -uall
1056  
1057  
1058  # Like testall, but with a single pass only
1059 @@ -725,7 +740,7 @@
1060                 distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
1061                 setuptools setuptools/command setuptools/tests setuptools.egg-info \
1062                 curses $(MACHDEPS)
1063 -libinstall:    $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR)
1064 +libinstall:    $(PYTHON_FOR_BUILD) $(srcdir)/Lib/$(PLATDIR)
1065         @for i in $(SCRIPTDIR) $(LIBDEST); \
1066         do \
1067                 if test ! -d $(DESTDIR)$$i; then \
1068 @@ -782,19 +797,19 @@
1069         done
1070         $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
1071         PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
1072 -               ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
1073 +               $(PYTHON_FOR_BUILD) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
1074                 -d $(LIBDEST) -f \
1075                 -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
1076         PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
1077 -               ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
1078 +               $(PYTHON_FOR_BUILD) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
1079                 -d $(LIBDEST) -f \
1080                 -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
1081         -PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
1082 -               ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
1083 +               $(PYTHON_FOR_BUILD) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
1084                 -d $(LIBDEST)/site-packages -f \
1085                 -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
1086         -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
1087 -               ./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
1088 +               $(PYTHON_FOR_BUILD) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
1089                 -d $(LIBDEST)/site-packages -f \
1090                 -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
1091  
1092 @@ -805,7 +820,7 @@
1093         export PATH; PATH="`pwd`:$$PATH"; \
1094         export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
1095         export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
1096 -       export EXE; EXE="$(BUILDEXE)"; \
1097 +       export EXE; EXE="$(EXEEXT)"; \
1098         cd $(srcdir)/Lib/$(PLATDIR); ./regen
1099  
1100  # Install the include files
1101 @@ -894,7 +909,9 @@
1102  # Install the dynamically loadable modules
1103  # This goes into $(exec_prefix)
1104  sharedinstall:
1105 -       $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
1106 +       CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' CROSS_COMPILING='$(CROSS
1107 +_COMPILING)' \
1108 +       $(RUNSHARED) ./$(PYTHON_FOR_BUILD) -E $(srcdir)/setup.py install \
1109                 --prefix=$(prefix) \
1110                 --install-scripts=$(BINDIR) \
1111                 --install-platlib=$(DESTSHARED) \
1112 @@ -967,8 +984,8 @@
1113  
1114  # This installs a few of the useful scripts in Tools/scripts
1115  scriptsinstall:
1116 -       SRCDIR=$(srcdir) $(RUNSHARED) \
1117 -       ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
1118 +       $(RUNSHARED) \
1119 +       $(PYTHON_FOR_BUILD) $(srcdir)/Tools/scripts/setup.py install \
1120         --prefix=$(prefix) \
1121         --install-scripts=$(BINDIR) \
1122         --root=/$(DESTDIR)
1123 @@ -988,6 +1005,11 @@
1124  .c.o:
1125         $(CC) -c $(PY_CFLAGS) -o $@ $<
1126  
1127 +# '.x' is the native object format during cross-compile.
1128 +.c.x:
1129 +       $(CC_FOR_BUILD) -c $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o $@ $<
1130 +.SUFFIXES: .x 
1131 +
1132  # Run reindent on the library
1133  reindent:
1134         ./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
1135 diff -urN Python-2.5.2.orig/Makefile.pre.in~ Python-2.5.2.mingw/Makefile.pre.in~
1136 --- Python-2.5.2.orig/Makefile.pre.in~  1970-01-01 01:00:00.000000000 +0100
1137 +++ Python-2.5.2.mingw/Makefile.pre.in~ 2008-10-06 18:43:25.000000000 +0100
1138 @@ -0,0 +1,1097 @@
1139 +# Top-level Makefile for Python
1140 +#
1141 +# As distributed, this file is called Makefile.pre.in; it is processed
1142 +# into the real Makefile by running the script ./configure, which
1143 +# replaces things like @spam@ with values appropriate for your system.
1144 +# This means that if you edit Makefile, your changes get lost the next
1145 +# time you run the configure script.  Ideally, you can do:
1146 +#
1147 +#      ./configure
1148 +#      make
1149 +#      make test
1150 +#      make install
1151 +#
1152 +# If you have a previous version of Python installed that you don't
1153 +# want to overwrite, you can use "make altinstall" instead of "make
1154 +# install".  Refer to the "Installing" section in the README file for
1155 +# additional details.
1156 +#
1157 +# See also the section "Build instructions" in the README file.
1158 +
1159 +# === Variables set by makesetup ===
1160 +
1161 +MODOBJS=        _MODOBJS_
1162 +MODLIBS=        _MODLIBS_
1163 +
1164 +# === Variables set by configure
1165 +VERSION=       @VERSION@
1166 +srcdir=                @srcdir@
1167 +VPATH=         @srcdir@
1168 +
1169 +CC=            @CC@
1170 +CXX=           @CXX@
1171 +MAINCC=                @MAINCC@
1172 +LINKCC=                @LINKCC@
1173 +AR=            @AR@
1174 +RANLIB=                @RANLIB@
1175 +SVNVERSION=    @SVNVERSION@
1176 +
1177 +# Shell used by make (some versions default to the login shell, which is bad)
1178 +SHELL=         /bin/sh
1179 +
1180 +# Use this to make a link between python$(VERSION) and python in $(BINDIR)
1181 +LN=            @LN@
1182 +
1183 +# Portable install script (configure doesn't always guess right)
1184 +INSTALL=       @INSTALL@
1185 +INSTALL_PROGRAM=@INSTALL_PROGRAM@
1186 +INSTALL_SCRIPT= @INSTALL_SCRIPT@
1187 +INSTALL_DATA=  @INSTALL_DATA@
1188 +# Shared libraries must be installed with executable mode on some systems;
1189 +# rather than figuring out exactly which, we always give them executable mode.
1190 +# Also, making them read-only seems to be a good idea...
1191 +INSTALL_SHARED= ${INSTALL} -m 555
1192 +
1193 +MAKESETUP=      $(srcdir)/Modules/makesetup
1194 +
1195 +# Compiler options
1196 +OPT=           @OPT@
1197 +BASECFLAGS=    @BASECFLAGS@
1198 +CFLAGS=                $(BASECFLAGS) $(OPT) $(EXTRA_CFLAGS)
1199 +# Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to
1200 +# be able to build extension modules using the directories specified in the
1201 +# environment variables
1202 +CPPFLAGS=      -I. -IInclude -I$(srcdir)/Include @CPPFLAGS@
1203 +LDFLAGS=       @LDFLAGS@
1204 +LDLAST=                @LDLAST@
1205 +SGI_ABI=       @SGI_ABI@
1206 +CCSHARED=      @CCSHARED@
1207 +LINKFORSHARED= @LINKFORSHARED@
1208 +# Extra C flags added for building the interpreter object files.
1209 +CFLAGSFORSHARED=@CFLAGSFORSHARED@
1210 +# C flags used for building the interpreter object files
1211 +PY_CFLAGS=     $(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
1212 +
1213 +
1214 +# Machine-dependent subdirectories
1215 +MACHDEP=       @MACHDEP@
1216 +
1217 +# Install prefix for architecture-independent files
1218 +prefix=                @prefix@
1219 +
1220 +# Install prefix for architecture-dependent files
1221 +exec_prefix=   @exec_prefix@
1222 +
1223 +# Install prefix for data files
1224 +datarootdir=    @datarootdir@
1225 +
1226 +# Expanded directories
1227 +BINDIR=                $(exec_prefix)/bin
1228 +LIBDIR=                $(exec_prefix)/lib64
1229 +MANDIR=                @mandir@
1230 +INCLUDEDIR=    @includedir@
1231 +CONFINCLUDEDIR=        $(exec_prefix)/include
1232 +SCRIPTDIR=     $(prefix)/lib64
1233 +
1234 +# Detailed destination directories
1235 +BINLIBDEST=    $(LIBDIR)/python$(VERSION)
1236 +LIBDEST=       $(SCRIPTDIR)/python$(VERSION)
1237 +INCLUDEPY=     $(INCLUDEDIR)/python$(VERSION)
1238 +CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(VERSION)
1239 +LIBP=          $(LIBDIR)/python$(VERSION)
1240 +
1241 +# Symbols used for using shared libraries
1242 +SO=            @SO@
1243 +LDSHARED=      @LDSHARED@
1244 +BLDSHARED=     @BLDSHARED@
1245 +DESTSHARED=    $(BINLIBDEST)/lib-dynload
1246 +
1247 +# Executable suffix (.exe on Windows and Mac OS X)
1248 +EXE=           @EXEEXT@
1249 +BUILDEXE=      @BUILDEXEEXT@
1250 +
1251 +# Short name and location for Mac OS X Python framework
1252 +UNIVERSALSDK=@UNIVERSALSDK@
1253 +PYTHONFRAMEWORK=       @PYTHONFRAMEWORK@
1254 +PYTHONFRAMEWORKDIR=    @PYTHONFRAMEWORKDIR@
1255 +PYTHONFRAMEWORKPREFIX= @PYTHONFRAMEWORKPREFIX@
1256 +PYTHONFRAMEWORKINSTALLDIR= @PYTHONFRAMEWORKINSTALLDIR@
1257 +# Deployment target selected during configure, to be checked
1258 +# by distutils. The export statement is needed to ensure that the
1259 +# deployment target is active during build.
1260 +MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@
1261 +@EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET
1262 +
1263 +# Options to enable prebinding (for fast startup prior to Mac OS X 10.3)
1264 +OTHER_LIBTOOL_OPT=@OTHER_LIBTOOL_OPT@
1265 +
1266 +# Environment to run shared python without installed libraries
1267 +RUNSHARED=       @RUNSHARED@
1268 +
1269 +# Modes for directories, executables and data files created by the
1270 +# install process.  Default to user-only-writable for all file types.
1271 +DIRMODE=       755
1272 +EXEMODE=       755
1273 +FILEMODE=      644
1274 +
1275 +# configure script arguments
1276 +CONFIG_ARGS=   @CONFIG_ARGS@
1277 +
1278 +
1279 +# Subdirectories with code
1280 +SRCDIRS=       @SRCDIRS@
1281 +
1282 +# Other subdirectories
1283 +SUBDIRSTOO=    Include Lib Misc Demo
1284 +
1285 +# Files and directories to be distributed
1286 +CONFIGFILES=   configure configure.in acconfig.h pyconfig.h.in Makefile.pre.in
1287 +DISTFILES=     README ChangeLog $(CONFIGFILES)
1288 +DISTDIRS=      $(SUBDIRS) $(SUBDIRSTOO) Ext-dummy
1289 +DIST=          $(DISTFILES) $(DISTDIRS)
1290 +
1291 +
1292 +LIBRARY=       @LIBRARY@
1293 +LDLIBRARY=      @LDLIBRARY@
1294 +BLDLIBRARY=     @BLDLIBRARY@
1295 +DLLLIBRARY=    @DLLLIBRARY@
1296 +LDLIBRARYDIR=   @LDLIBRARYDIR@
1297 +INSTSONAME=    @INSTSONAME@
1298 +
1299 +
1300 +LIBS=          @LIBS@
1301 +LIBM=          @LIBM@
1302 +LIBC=          @LIBC@
1303 +SYSLIBS=       $(LIBM) $(LIBC)
1304 +SHLIBS=                @SHLIBS@
1305 +
1306 +THREADOBJ=     @THREADOBJ@
1307 +DLINCLDIR=     @DLINCLDIR@
1308 +DYNLOADFILE=   @DYNLOADFILE@
1309 +MACHDEP_OBJS=  @MACHDEP_OBJS@
1310 +UNICODE_OBJS=   @UNICODE_OBJS@
1311 +
1312 +PYTHON=                python$(EXE)
1313 +BUILDPYTHON=   python$(BUILDEXE)
1314 +
1315 +# === Definitions added by makesetup ===
1316 +
1317 +
1318 +##########################################################################
1319 +# Modules
1320 +MODULE_OBJS=   \
1321 +               Modules/config.o \
1322 +               Modules/getpath.o \
1323 +               Modules/main.o \
1324 +               Modules/gcmodule.o
1325 +
1326 +# Used of signalmodule.o is not available
1327 +SIGNAL_OBJS=   @SIGNAL_OBJS@
1328 +
1329 +
1330 +##########################################################################
1331 +# Grammar
1332 +GRAMMAR_H=     $(srcdir)/Include/graminit.h
1333 +GRAMMAR_C=     $(srcdir)/Python/graminit.c
1334 +GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar
1335 +
1336 +
1337 +##########################################################################
1338 +# Parser
1339 +PGEN=          Parser/pgen$(EXE)
1340 +
1341 +POBJS=         \
1342 +               Parser/acceler.o \
1343 +               Parser/grammar1.o \
1344 +               Parser/listnode.o \
1345 +               Parser/node.o \
1346 +               Parser/parser.o \
1347 +               Parser/parsetok.o \
1348 +               Parser/bitset.o \
1349 +               Parser/metagrammar.o \
1350 +               Parser/firstsets.o \
1351 +               Parser/grammar.o \
1352 +               Parser/pgen.o
1353 +
1354 +PARSER_OBJS=   $(POBJS) Parser/myreadline.o Parser/tokenizer.o
1355 +
1356 +PGOBJS=                \
1357 +               Objects/obmalloc.o \
1358 +               Python/mysnprintf.o \
1359 +               Parser/tokenizer_pgen.o \
1360 +               Parser/printgrammar.o \
1361 +               Parser/pgenmain.o
1362 +
1363 +PGENOBJS=      $(PGENMAIN) $(POBJS) $(PGOBJS)
1364 +
1365 +##########################################################################
1366 +# AST
1367 +AST_H_DIR=     $(srcdir)/Include
1368 +AST_H=         $(AST_H_DIR)/Python-ast.h
1369 +AST_C_DIR=     $(srcdir)/Python
1370 +AST_C=         $(AST_C_DIR)/Python-ast.c
1371 +AST_ASDL=      $(srcdir)/Parser/Python.asdl
1372 +
1373 +ASDLGEN_FILES= $(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py
1374 +# XXX Note that a build now requires Python exist before the build starts
1375 +ASDLGEN=       $(srcdir)/Parser/asdl_c.py
1376 +
1377 +##########################################################################
1378 +# Python
1379 +PYTHON_OBJS=   \
1380 +               Python/Python-ast.o \
1381 +               Python/asdl.o \
1382 +               Python/ast.o \
1383 +               Python/bltinmodule.o \
1384 +               Python/ceval.o \
1385 +               Python/compile.o \
1386 +               Python/codecs.o \
1387 +               Python/errors.o \
1388 +               Python/frozen.o \
1389 +               Python/frozenmain.o \
1390 +               Python/future.o \
1391 +               Python/getargs.o \
1392 +               Python/getcompiler.o \
1393 +               Python/getcopyright.o \
1394 +               Python/getmtime.o \
1395 +               Python/getplatform.o \
1396 +               Python/getversion.o \
1397 +               Python/graminit.o \
1398 +               Python/import.o \
1399 +               Python/importdl.o \
1400 +               Python/marshal.o \
1401 +               Python/modsupport.o \
1402 +               Python/mystrtoul.o \
1403 +               Python/mysnprintf.o \
1404 +               Python/pyarena.o \
1405 +               Python/pyfpe.o \
1406 +               Python/pystate.o \
1407 +               Python/pythonrun.o \
1408 +               Python/structmember.o \
1409 +               Python/symtable.o \
1410 +               Python/sysmodule.o \
1411 +               Python/traceback.o \
1412 +               Python/getopt.o \
1413 +               Python/pystrtod.o \
1414 +               Python/$(DYNLOADFILE) \
1415 +               $(MACHDEP_OBJS) \
1416 +               $(THREADOBJ)
1417 +
1418 +
1419 +##########################################################################
1420 +# Objects
1421 +OBJECT_OBJS=   \
1422 +               Objects/abstract.o \
1423 +               Objects/boolobject.o \
1424 +               Objects/bufferobject.o \
1425 +               Objects/cellobject.o \
1426 +               Objects/classobject.o \
1427 +               Objects/cobject.o \
1428 +               Objects/codeobject.o \
1429 +               Objects/complexobject.o \
1430 +               Objects/descrobject.o \
1431 +               Objects/enumobject.o \
1432 +               Objects/exceptions.o \
1433 +               Objects/genobject.o \
1434 +               Objects/fileobject.o \
1435 +               Objects/floatobject.o \
1436 +               Objects/frameobject.o \
1437 +               Objects/funcobject.o \
1438 +               Objects/intobject.o \
1439 +               Objects/iterobject.o \
1440 +               Objects/listobject.o \
1441 +               Objects/longobject.o \
1442 +               Objects/dictobject.o \
1443 +               Objects/methodobject.o \
1444 +               Objects/moduleobject.o \
1445 +               Objects/object.o \
1446 +               Objects/obmalloc.o \
1447 +               Objects/rangeobject.o \
1448 +                Objects/setobject.o \
1449 +               Objects/sliceobject.o \
1450 +               Objects/stringobject.o \
1451 +               Objects/structseq.o \
1452 +               Objects/tupleobject.o \
1453 +               Objects/typeobject.o \
1454 +               Objects/weakrefobject.o \
1455 +               $(UNICODE_OBJS)
1456 +
1457 +
1458 +##########################################################################
1459 +# objects that get linked into the Python library
1460 +LIBRARY_OBJS=  \
1461 +               Modules/_typesmodule.o \
1462 +               Modules/getbuildinfo.o \
1463 +               $(PARSER_OBJS) \
1464 +               $(OBJECT_OBJS) \
1465 +               $(PYTHON_OBJS) \
1466 +               $(MODULE_OBJS) \
1467 +               $(SIGNAL_OBJS) \
1468 +               $(MODOBJS)
1469 +
1470 +#########################################################################
1471 +# Rules
1472 +
1473 +# Default target
1474 +all:           $(BUILDPYTHON) oldsharedmods sharedmods
1475 +
1476 +# Build the interpreter
1477 +$(BUILDPYTHON):        Modules/python.o $(LIBRARY) $(LDLIBRARY)
1478 +               $(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
1479 +                       Modules/python.o \
1480 +                       $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
1481 +
1482 +platform: $(BUILDPYTHON)
1483 +       $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
1484 +
1485 +
1486 +# Build the shared modules
1487 +sharedmods: $(BUILDPYTHON)
1488 +       case $$MAKEFLAGS in \
1489 +       *-s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
1490 +       *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
1491 +       esac
1492 +
1493 +# Build static library
1494 +# avoid long command lines, same as LIBRARY_OBJS
1495 +$(LIBRARY): $(LIBRARY_OBJS)
1496 +       -rm -f $@
1497 +       $(AR) cr $@ Modules/getbuildinfo.o
1498 +       $(AR) cr $@ Modules/_typesmodule.o
1499 +       $(AR) cr $@ $(PARSER_OBJS)
1500 +       $(AR) cr $@ $(OBJECT_OBJS)
1501 +       $(AR) cr $@ $(PYTHON_OBJS)
1502 +       $(AR) cr $@ $(MODULE_OBJS) $(SIGNAL_OBJS)
1503 +       $(AR) cr $@ $(MODOBJS)
1504 +       $(RANLIB) $@
1505 +
1506 +libpython$(VERSION).so: $(LIBRARY_OBJS)
1507 +       if test $(INSTSONAME) != $(LDLIBRARY); then \
1508 +               $(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
1509 +               $(LN) -f $(INSTSONAME) $@; \
1510 +       else\
1511 +               $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
1512 +       fi
1513 +
1514 +libpython$(VERSION).sl: $(LIBRARY_OBJS)
1515 +       $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM)
1516 +
1517 +# This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary
1518 +# minimal framework (not including the Lib directory and such) in the current
1519 +# directory.
1520 +RESSRCDIR=$(srcdir)/Mac/Resources/framework
1521 +$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
1522 +               $(LIBRARY) \
1523 +               $(RESSRCDIR)/Info.plist \
1524 +                $(RESSRCDIR)/version.plist \
1525 +                $(RESSRCDIR)/English.lproj/InfoPlist.strings
1526 +       $(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)
1527 +       if test "${UNIVERSALSDK}"; then \
1528 +               $(CC) -o $(LDLIBRARY) -arch i386 -arch ppc -dynamiclib \
1529 +                       -isysroot "${UNIVERSALSDK}" \
1530 +                       -all_load $(LIBRARY) -Wl,-single_module \
1531 +                       -install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/Python \
1532 +                       -compatibility_version $(VERSION) \
1533 +                       -current_version $(VERSION); \
1534 +        else \
1535 +               /usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
1536 +                       @LIBTOOL_CRUFT@ ;\
1537 +       fi
1538 +       $(INSTALL) -d -m $(DIRMODE)  \
1539 +               $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj
1540 +       $(INSTALL_DATA) $(RESSRCDIR)/Info.plist \
1541 +               $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/Info.plist
1542 +       $(INSTALL_DATA) $(RESSRCDIR)/version.plist \
1543 +               $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/version.plist
1544 +       $(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
1545 +               $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj/InfoPlist.strings
1546 +       $(LN) -fsn $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current
1547 +       $(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)
1548 +       $(LN) -fsn Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers
1549 +       $(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources
1550 +
1551 +# This rule builds the Cygwin Python DLL and import library if configured
1552 +# for a shared core library; otherwise, this rule is a noop.
1553 +$(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS)
1554 +       if test -n "$(DLLLIBRARY)"; then \
1555 +               $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \
1556 +                       $(LIBS) $(MODLIBS) $(SYSLIBS); \
1557 +       else true; \
1558 +       fi
1559 +
1560 +
1561 +oldsharedmods: $(SHAREDMODS)
1562 +
1563 +
1564 +Makefile Modules/config.c: Makefile.pre \
1565 +                               $(srcdir)/Modules/config.c.in \
1566 +                               $(MAKESETUP) \
1567 +                               Modules/Setup.config \
1568 +                               Modules/Setup \
1569 +                               Modules/Setup.local
1570 +       $(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
1571 +                               -s Modules \
1572 +                               Modules/Setup.config \
1573 +                               Modules/Setup.local \
1574 +                               Modules/Setup
1575 +       @mv config.c Modules
1576 +       @echo "The Makefile was updated, you may need to re-run make."
1577 +
1578 +
1579 +Modules/Setup: $(srcdir)/Modules/Setup.dist
1580 +       @if test -f Modules/Setup; then \
1581 +               echo "-----------------------------------------------"; \
1582 +               echo "Modules/Setup.dist is newer than Modules/Setup;"; \
1583 +               echo "check to make sure you have all the updates you"; \
1584 +               echo "need in your Modules/Setup file."; \
1585 +               echo "Usually, copying Setup.dist to Setup will work."; \
1586 +               echo "-----------------------------------------------"; \
1587 +       fi
1588 +
1589 +############################################################################
1590 +# Special rules for object files
1591 +
1592 +Modules/getbuildinfo.o: $(PARSER_OBJS) \
1593 +               $(OBJECT_OBJS) \
1594 +               $(PYTHON_OBJS) \
1595 +               $(MODULE_OBJS) \
1596 +               $(SIGNAL_OBJS) \
1597 +               $(MODOBJS) \
1598 +               $(srcdir)/Modules/getbuildinfo.c
1599 +       $(CC) -c $(PY_CFLAGS) -DSVNVERSION=\"`LC_ALL=C $(SVNVERSION)`\" -o $@ $(srcdir)/Modules/getbuildinfo.c
1600 +
1601 +Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
1602 +       $(CC) -c $(PY_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
1603 +               -DPREFIX='"$(prefix)"' \
1604 +               -DEXEC_PREFIX='"$(exec_prefix)"' \
1605 +               -DVERSION='"$(VERSION)"' \
1606 +               -DVPATH='"$(VPATH)"' \
1607 +               -o $@ $(srcdir)/Modules/getpath.c
1608 +
1609 +Modules/python.o: $(srcdir)/Modules/python.c
1610 +       $(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
1611 +
1612 +
1613 +$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
1614 +               -@ mkdir Include
1615 +               -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
1616 +
1617 +$(PGEN):       $(PGENOBJS)
1618 +               $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
1619 +
1620 +Parser/grammar.o:      $(srcdir)/Parser/grammar.c \
1621 +                               $(srcdir)/Include/token.h \
1622 +                               $(srcdir)/Include/grammar.h
1623 +Parser/metagrammar.o:  $(srcdir)/Parser/metagrammar.c
1624 +
1625 +Parser/tokenizer_pgen.o:       $(srcdir)/Parser/tokenizer.c
1626 +
1627 +$(AST_H): $(AST_ASDL) $(ASDLGEN_FILES)
1628 +       $(ASDLGEN) -h $(AST_H_DIR) $(AST_ASDL)
1629 +
1630 +$(AST_C): $(AST_ASDL) $(ASDLGEN_FILES)
1631 +       $(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL)
1632 +
1633 +Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H)
1634 +
1635 +Python/getplatform.o: $(srcdir)/Python/getplatform.c
1636 +               $(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
1637 +
1638 +Python/importdl.o: $(srcdir)/Python/importdl.c
1639 +               $(CC) -c $(PY_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c
1640 +
1641 +Objects/unicodectype.o:        $(srcdir)/Objects/unicodectype.c \
1642 +                               $(srcdir)/Objects/unicodetype_db.h
1643 +
1644 +############################################################################
1645 +# Header files
1646 +
1647 +PYTHON_HEADERS= \
1648 +               Include/Python.h \
1649 +               Include/Python-ast.h \
1650 +               Include/asdl.h \
1651 +               Include/abstract.h \
1652 +               Include/boolobject.h \
1653 +               Include/bufferobject.h \
1654 +               Include/ceval.h \
1655 +               Include/classobject.h \
1656 +               Include/cobject.h \
1657 +               Include/code.h \
1658 +               Include/codecs.h \
1659 +               Include/compile.h \
1660 +               Include/complexobject.h \
1661 +               Include/descrobject.h \
1662 +               Include/dictobject.h \
1663 +               Include/enumobject.h \
1664 +               Include/genobject.h \
1665 +               Include/fileobject.h \
1666 +               Include/floatobject.h \
1667 +               Include/funcobject.h \
1668 +               Include/import.h \
1669 +               Include/intobject.h \
1670 +               Include/intrcheck.h \
1671 +               Include/iterobject.h \
1672 +               Include/listobject.h \
1673 +               Include/longobject.h \
1674 +               Include/methodobject.h \
1675 +               Include/modsupport.h \
1676 +               Include/moduleobject.h \
1677 +               Include/object.h \
1678 +               Include/objimpl.h \
1679 +               Include/patchlevel.h \
1680 +               Include/pyarena.h \
1681 +               Include/pydebug.h \
1682 +               Include/pyerrors.h \
1683 +               Include/pyfpe.h \
1684 +               Include/pymem.h \
1685 +               Include/pyport.h \
1686 +               Include/pystate.h \
1687 +               Include/pythonrun.h \
1688 +               Include/rangeobject.h \
1689 +                Include/setobject.h \
1690 +               Include/sliceobject.h \
1691 +               Include/stringobject.h \
1692 +               Include/structseq.h \
1693 +               Include/structmember.h \
1694 +               Include/symtable.h \
1695 +               Include/sysmodule.h \
1696 +               Include/traceback.h \
1697 +               Include/tupleobject.h \
1698 +               Include/unicodeobject.h \
1699 +               Include/weakrefobject.h \
1700 +               pyconfig.h
1701 +
1702 +$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
1703 +
1704 +
1705 +######################################################################
1706 +
1707 +# Test the interpreter (twice, once without .pyc files, once with)
1708 +# In the past, we've had problems where bugs in the marshalling or
1709 +# elsewhere caused bytecode read from .pyc files to behave differently
1710 +# than bytecode generated directly from a .py source file.  Sometimes
1711 +# the bytecode read from a .pyc file had the bug, somtimes the directly
1712 +# generated bytecode.  This is sometimes a very shy bug needing a lot of
1713 +# sample data.
1714 +
1715 +TESTOPTS=      -l $(EXTRATESTOPTS)
1716 +TESTPROG=      $(srcdir)/Lib/test/regrtest.py
1717 +TESTPYTHON=    $(RUNSHARED) ./$(BUILDPYTHON) -E -tt
1718 +test:          all platform
1719 +               -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1720 +               -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
1721 +               $(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
1722 +
1723 +testall:       all platform
1724 +               -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1725 +               -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1726 +               $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1727 +
1728 +#  Run the unitests for both architectures in a Universal build on OSX
1729 +#  Must be run on an Intel box.
1730 +testuniversal: all platform
1731 +               if [ `arch` != 'i386' ];then \
1732 +                       echo "This can only be used on OSX/i386" ;\
1733 +                       exit 1 ;\
1734 +               fi
1735 +               -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1736 +               -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1737 +               $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
1738 +               $(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
1739 +
1740 +
1741 +# Like testall, but with a single pass only
1742 +# run an optional script to include some information about the build environment
1743 +buildbottest:  all platform
1744 +               -@if which pybuildbot.identify >/dev/null 2>&1; then \
1745 +                       pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \
1746 +               fi
1747 +               $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw
1748 +
1749 +QUICKTESTOPTS= $(TESTOPTS) -x test_thread test_signal test_strftime \
1750 +               test_unicodedata test_re test_sre test_select test_poll \
1751 +               test_linuxaudiodev test_struct test_sunaudiodev test_zlib
1752 +quicktest:     all platform
1753 +               -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1754 +               -$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
1755 +               $(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
1756 +
1757 +MEMTESTOPTS=    $(QUICKTESTOPTS) -x test_dl test___all__ test_fork1 \
1758 +               test_longexp
1759 +memtest:       all platform
1760 +               -rm -f $(srcdir)/Lib/test/*.py[co]
1761 +               -$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
1762 +               $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
1763 +
1764 +# Install everything
1765 +install:       @FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@
1766 +
1767 +# Install almost everything without disturbing previous versions
1768 +altinstall:    @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \
1769 +                sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@
1770 +
1771 +# Install shared libraries enabled by Setup
1772 +DESTDIRS=      $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED)
1773 +
1774 +oldsharedinstall: $(DESTSHARED) $(SHAREDMODS)
1775 +               @for i in X $(SHAREDMODS); do \
1776 +                 if test $$i != X; then \
1777 +                   echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \
1778 +                   $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \
1779 +                 fi; \
1780 +               done
1781 +
1782 +$(DESTSHARED):
1783 +               @for i in $(DESTDIRS); \
1784 +               do \
1785 +                       if test ! -d $(DESTDIR)$$i; then \
1786 +                               echo "Creating directory $$i"; \
1787 +                               $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1788 +                       else    true; \
1789 +                       fi; \
1790 +               done
1791 +
1792 +
1793 +# Install the interpreter (by creating a hard link to python$(VERSION))
1794 +bininstall:    altbininstall
1795 +       -if test -f $(DESTDIR)$(BINDIR)/$(PYTHON) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON); \
1796 +       then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \
1797 +       else true; \
1798 +       fi
1799 +       (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON))
1800 +       -rm -f $(DESTDIR)$(BINDIR)/python-config
1801 +       (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python-config)
1802 +
1803 +# Install the interpreter with $(VERSION) affixed
1804 +# This goes into $(exec_prefix)
1805 +altbininstall: $(BUILDPYTHON)
1806 +       @for i in $(BINDIR) $(LIBDIR); \
1807 +       do \
1808 +               if test ! -d $(DESTDIR)$$i; then \
1809 +                       echo "Creating directory $$i"; \
1810 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1811 +               else    true; \
1812 +               fi; \
1813 +       done
1814 +       $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE)
1815 +       if test -f libpython$(VERSION)$(SO); then \
1816 +               if test "$(SO)" = .dll; then \
1817 +                       $(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(BINDIR); \
1818 +               else \
1819 +                       $(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
1820 +                       if test libpython$(VERSION)$(SO) != $(INSTSONAME); then \
1821 +                               (cd $(DESTDIR)$(LIBDIR); $(LN) -sf $(INSTSONAME) libpython$(VERSION)$(SO)); \
1822 +                       fi \
1823 +               fi; \
1824 +       else    true; \
1825 +       fi
1826 +
1827 +# Install the manual page
1828 +maninstall:
1829 +       @for i in $(MANDIR) $(MANDIR)/man1; \
1830 +       do \
1831 +               if test ! -d $(DESTDIR)$$i; then \
1832 +                       echo "Creating directory $$i"; \
1833 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1834 +               else    true; \
1835 +               fi; \
1836 +       done
1837 +       $(INSTALL_DATA) $(srcdir)/Misc/python.man \
1838 +               $(DESTDIR)$(MANDIR)/man1/python.1
1839 +
1840 +# Install the library
1841 +PLATDIR=       plat-$(MACHDEP)
1842 +EXTRAPLATDIR= @EXTRAPLATDIR@
1843 +EXTRAMACHDEPPATH=@EXTRAMACHDEPPATH@
1844 +MACHDEPS=      $(PLATDIR) $(EXTRAPLATDIR)
1845 +XMLLIBSUBDIRS=  xml xml/dom xml/etree xml/parsers xml/sax
1846 +PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \
1847 +       plat-mac/lib-scriptpackages/_builtinSuites \
1848 +       plat-mac/lib-scriptpackages/CodeWarrior \
1849 +       plat-mac/lib-scriptpackages/Explorer \
1850 +       plat-mac/lib-scriptpackages/Finder \
1851 +       plat-mac/lib-scriptpackages/Netscape \
1852 +       plat-mac/lib-scriptpackages/StdSuites \
1853 +       plat-mac/lib-scriptpackages/SystemEvents \
1854 +       plat-mac/lib-scriptpackages/Terminal 
1855 +PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages
1856 +LIBSUBDIRS=    lib-tk site-packages test test/output test/data \
1857 +               test/decimaltestdata \
1858 +               encodings compiler hotshot \
1859 +               email email/mime email/test email/test/data \
1860 +               sqlite3 sqlite3/test \
1861 +               logging bsddb bsddb/test csv wsgiref \
1862 +               ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
1863 +               distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
1864 +               setuptools setuptools/command setuptools/tests setuptools.egg-info \
1865 +               curses $(MACHDEPS)
1866 +libinstall:    $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR)
1867 +       @for i in $(SCRIPTDIR) $(LIBDEST); \
1868 +       do \
1869 +               if test ! -d $(DESTDIR)$$i; then \
1870 +                       echo "Creating directory $$i"; \
1871 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1872 +               else    true; \
1873 +               fi; \
1874 +       done
1875 +       @for d in $(LIBSUBDIRS); \
1876 +       do \
1877 +               a=$(srcdir)/Lib/$$d; \
1878 +               if test ! -d $$a; then continue; else true; fi; \
1879 +               b=$(LIBDEST)/$$d; \
1880 +               if test ! -d $(DESTDIR)$$b; then \
1881 +                       echo "Creating directory $$b"; \
1882 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$b; \
1883 +               else    true; \
1884 +               fi; \
1885 +       done
1886 +       @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.doc $(srcdir)/Lib/*.egg-info ; \
1887 +       do \
1888 +               if test -x $$i; then \
1889 +                       $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \
1890 +                       echo $(INSTALL_SCRIPT) $$i $(LIBDEST); \
1891 +               else \
1892 +                       $(INSTALL_DATA) $$i $(DESTDIR)$(LIBDEST); \
1893 +                       echo $(INSTALL_DATA) $$i $(LIBDEST); \
1894 +               fi; \
1895 +       done
1896 +       @for d in $(LIBSUBDIRS); \
1897 +       do \
1898 +               a=$(srcdir)/Lib/$$d; \
1899 +               if test ! -d $$a; then continue; else true; fi; \
1900 +               if test `ls $$a | wc -l` -lt 1; then continue; fi; \
1901 +               b=$(LIBDEST)/$$d; \
1902 +               for i in $$a/*; \
1903 +               do \
1904 +                       case $$i in \
1905 +                       *CVS) ;; \
1906 +                       *.py[co]) ;; \
1907 +                       *.orig) ;; \
1908 +                       *~) ;; \
1909 +                       *) \
1910 +                               if test -d $$i; then continue; fi; \
1911 +                               if test -x $$i; then \
1912 +                                   echo $(INSTALL_SCRIPT) $$i $$b; \
1913 +                                   $(INSTALL_SCRIPT) $$i $(DESTDIR)$$b; \
1914 +                               else \
1915 +                                   echo $(INSTALL_DATA) $$i $$b; \
1916 +                                   $(INSTALL_DATA) $$i $(DESTDIR)$$b; \
1917 +                               fi;; \
1918 +                       esac; \
1919 +               done; \
1920 +       done
1921 +       $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
1922 +       PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
1923 +               ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
1924 +               -d $(LIBDEST) -f \
1925 +               -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
1926 +       PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
1927 +               ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
1928 +               -d $(LIBDEST) -f \
1929 +               -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
1930 +       -PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
1931 +               ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
1932 +               -d $(LIBDEST)/site-packages -f \
1933 +               -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
1934 +       -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
1935 +               ./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
1936 +               -d $(LIBDEST)/site-packages -f \
1937 +               -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
1938 +
1939 +# Create the PLATDIR source directory, if one wasn't distributed..
1940 +$(srcdir)/Lib/$(PLATDIR):
1941 +       mkdir $(srcdir)/Lib/$(PLATDIR)
1942 +       cp $(srcdir)/Lib/plat-generic/regen $(srcdir)/Lib/$(PLATDIR)/regen
1943 +       export PATH; PATH="`pwd`:$$PATH"; \
1944 +       export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
1945 +       export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
1946 +       export EXE; EXE="$(BUILDEXE)"; \
1947 +       cd $(srcdir)/Lib/$(PLATDIR); ./regen
1948 +
1949 +# Install the include files
1950 +INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY)
1951 +inclinstall:
1952 +       @for i in $(INCLDIRSTOMAKE); \
1953 +       do \
1954 +               if test ! -d $(DESTDIR)$$i; then \
1955 +                       echo "Creating directory $$i"; \
1956 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1957 +               else    true; \
1958 +               fi; \
1959 +       done
1960 +       @for i in $(srcdir)/Include/*.h; \
1961 +       do \
1962 +               echo $(INSTALL_DATA) $$i $(INCLUDEPY); \
1963 +               $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \
1964 +       done
1965 +       $(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h
1966 +
1967 +# Install the library and miscellaneous stuff needed for extending/embedding
1968 +# This goes into $(exec_prefix)
1969 +LIBPL=         $(LIBP)/config
1970 +libainstall:   all
1971 +       @for i in $(LIBDIR) $(LIBP) $(LIBPL); \
1972 +       do \
1973 +               if test ! -d $(DESTDIR)$$i; then \
1974 +                       echo "Creating directory $$i"; \
1975 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1976 +               else    true; \
1977 +               fi; \
1978 +       done
1979 +       @if test -d $(LIBRARY); then :; else \
1980 +               if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
1981 +                       if test "$(SO)" = .dll; then \
1982 +                               $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \
1983 +                       else \
1984 +                               $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
1985 +                               $(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
1986 +                       fi; \
1987 +               else \
1988 +                       echo Skip install of $(LIBRARY) - use make frameworkinstall; \
1989 +               fi; \
1990 +       fi
1991 +       $(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c
1992 +       $(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o
1993 +       $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in
1994 +       $(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
1995 +       $(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
1996 +       $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
1997 +       $(INSTALL_DATA) Modules/Setup.config $(DESTDIR)$(LIBPL)/Setup.config
1998 +       $(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
1999 +       $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
2000 +       # Substitution happens here, as the completely-expanded BINDIR
2001 +       # is not available in configure
2002 +       sed -e "s,@EXENAME@,$(BINDIR)/python$(VERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config
2003 +       $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(VERSION)-config
2004 +       rm python-config
2005 +       @if [ -s Modules/python.exp -a \
2006 +               "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \
2007 +               echo; echo "Installing support files for building shared extension modules on AIX:"; \
2008 +               $(INSTALL_DATA) Modules/python.exp              \
2009 +                               $(DESTDIR)$(LIBPL)/python.exp;          \
2010 +               echo; echo "$(LIBPL)/python.exp";               \
2011 +               $(INSTALL_SCRIPT) $(srcdir)/Modules/makexp_aix  \
2012 +                               $(DESTDIR)$(LIBPL)/makexp_aix;          \
2013 +               echo "$(LIBPL)/makexp_aix";                     \
2014 +               $(INSTALL_SCRIPT) $(srcdir)/Modules/ld_so_aix   \
2015 +                               $(DESTDIR)$(LIBPL)/ld_so_aix;           \
2016 +               echo "$(LIBPL)/ld_so_aix";                      \
2017 +               echo; echo "See Misc/AIX-NOTES for details.";   \
2018 +       else true; \
2019 +       fi
2020 +       @case "$(MACHDEP)" in beos*) \
2021 +               echo; echo "Installing support files for building shared extension modules on BeOS:"; \
2022 +               $(INSTALL_DATA) Misc/BeOS-NOTES $(DESTDIR)$(LIBPL)/README;      \
2023 +               echo; echo "$(LIBPL)/README";                   \
2024 +               $(INSTALL_SCRIPT) Modules/ar_beos $(DESTDIR)$(LIBPL)/ar_beos; \
2025 +               echo "$(LIBPL)/ar_beos";                        \
2026 +               $(INSTALL_SCRIPT) Modules/ld_so_beos $(DESTDIR)$(LIBPL)/ld_so_beos; \
2027 +               echo "$(LIBPL)/ld_so_beos";                     \
2028 +               echo; echo "See Misc/BeOS-NOTES for details.";  \
2029 +               ;; \
2030 +       esac
2031 +
2032 +# Install the dynamically loadable modules
2033 +# This goes into $(exec_prefix)
2034 +sharedinstall:
2035 +       $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
2036 +               --prefix=$(prefix) \
2037 +               --install-scripts=$(BINDIR) \
2038 +               --install-platlib=$(DESTSHARED) \
2039 +               --root=/$(DESTDIR)
2040 +
2041 +# Here are a couple of targets for MacOSX again, to install a full
2042 +# framework-based Python. frameworkinstall installs everything, the
2043 +# subtargets install specific parts. Much of the actual work is offloaded to
2044 +# the Makefile in Mac
2045 +#
2046 +#
2047 +# This target is here for backward compatiblity, previous versions of Python
2048 +# hadn't integrated framework installation in the normal install process.
2049 +frameworkinstall: install
2050 +
2051 +# On install, we re-make the framework
2052 +# structure in the install location, /Library/Frameworks/ or the argument to
2053 +# --enable-framework. If --enable-framework has been specified then we have
2054 +# automatically set prefix to the location deep down in the framework, so we
2055 +# only have to cater for the structural bits of the framework.
2056 +
2057 +frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib
2058 +
2059 +frameworkinstallstructure:     $(LDLIBRARY)
2060 +       @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
2061 +               echo Not configured with --enable-framework; \
2062 +               exit 1; \
2063 +       else true; \
2064 +       fi
2065 +       @for i in $(prefix)/Resources/English.lproj $(prefix)/lib; do\
2066 +               if test ! -d $(DESTDIR)$$i; then \
2067 +                       echo "Creating directory $(DESTDIR)$$i"; \
2068 +                       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
2069 +               else    true; \
2070 +               fi; \
2071 +       done
2072 +       $(LN) -fsn include/python$(VERSION) $(DESTDIR)$(prefix)/Headers
2073 +       $(INSTALL_DATA) $(RESSRCDIR)/Info.plist $(DESTDIR)$(prefix)/Resources/Info.plist
2074 +       $(INSTALL_DATA) $(RESSRCDIR)/version.plist $(DESTDIR)$(prefix)/Resources/version.plist
2075 +       $(INSTALL_DATA) $(RESSRCDIR)/English.lproj/InfoPlist.strings \
2076 +               $(DESTDIR)$(prefix)/Resources/English.lproj/InfoPlist.strings
2077 +       $(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current
2078 +       $(LN) -fsn Versions/Current/Python $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Python
2079 +       $(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers
2080 +       $(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources
2081 +       $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
2082 +
2083 +# This installs Mac/Lib into the framework
2084 +# Install a number of symlinks to keep software that expects a normal unix
2085 +# install (which includes python-config) happy.
2086 +frameworkinstallmaclib:
2087 +       ln -fs "../../../Python" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a"
2088 +       cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)"
2089 +
2090 +# This installs the IDE, the Launcher and other apps into /Applications
2091 +frameworkinstallapps:
2092 +       cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)"
2093 +
2094 +# This install the unix python and pythonw tools in /usr/local/bin
2095 +frameworkinstallunixtools:
2096 +       cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)"
2097 +
2098 +frameworkaltinstallunixtools:
2099 +       cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)"
2100 +
2101 +# This installs the Demos and Tools into the applications directory.
2102 +# It is not part of a normal frameworkinstall
2103 +frameworkinstallextras:
2104 +       cd Mac && Make installextras DESTDIR="$(DESTDIR)"
2105 +
2106 +# This installs a few of the useful scripts in Tools/scripts
2107 +scriptsinstall:
2108 +       SRCDIR=$(srcdir) $(RUNSHARED) \
2109 +       ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
2110 +       --prefix=$(prefix) \
2111 +       --install-scripts=$(BINDIR) \
2112 +       --root=/$(DESTDIR)
2113 +
2114 +# Build the toplevel Makefile
2115 +Makefile.pre: Makefile.pre.in config.status
2116 +       CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status
2117 +       $(MAKE) -f Makefile.pre Makefile
2118 +
2119 +# Run the configure script.
2120 +config.status: $(srcdir)/configure
2121 +       $(SHELL) $(srcdir)/configure $(CONFIG_ARGS)
2122 +
2123 +.PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre
2124 +
2125 +# Some make's put the object file in the current directory
2126 +.c.o:
2127 +       $(CC) -c $(PY_CFLAGS) -o $@ $<
2128 +
2129 +# Run reindent on the library
2130 +reindent:
2131 +       ./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
2132 +
2133 +# Rerun configure with the same options as it was run last time,
2134 +# provided the config.status script exists
2135 +recheck:
2136 +       $(SHELL) config.status --recheck
2137 +       $(SHELL) config.status
2138 +
2139 +# Rebuild the configure script from configure.in; also rebuild pyconfig.h.in
2140 +autoconf:
2141 +       (cd $(srcdir); autoconf)
2142 +       (cd $(srcdir); autoheader)
2143 +
2144 +# Create a tags file for vi
2145 +tags::
2146 +       cd $(srcdir); \
2147 +       ctags -w -t Include/*.h; \
2148 +       for i in $(SRCDIRS); do ctags -w -t -a $$i/*.[ch]; \
2149 +       done; \
2150 +       sort -o tags tags
2151 +
2152 +# Create a tags file for GNU Emacs
2153 +TAGS::
2154 +       cd $(srcdir); \
2155 +       etags Include/*.h; \
2156 +       for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done
2157 +
2158 +# Sanitation targets -- clean leaves libraries, executables and tags
2159 +# files, which clobber removes those as well
2160 +pycremoval:
2161 +       find $(srcdir) -name '*.py[co]' -exec rm -f {} ';'
2162 +
2163 +clean: pycremoval
2164 +       find . -name '*.o' -exec rm -f {} ';'
2165 +       find . -name '*.s[ol]' -exec rm -f {} ';'
2166 +       find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true
2167 +       find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true
2168 +
2169 +clobber: clean
2170 +       -rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
2171 +               tags TAGS \
2172 +               config.cache config.log pyconfig.h Modules/config.c
2173 +       -rm -rf build platform
2174 +       -rm -rf $(PYTHONFRAMEWORKDIR)
2175 +
2176 +# Make things extra clean, before making a distribution:
2177 +# remove all generated files, even Makefile[.pre]
2178 +# Keep configure and Python-ast.[ch], it's possible they can't be generated
2179 +distclean: clobber
2180 +       -rm -f core Makefile Makefile.pre config.status \
2181 +               Modules/Setup Modules/Setup.local Modules/Setup.config
2182 +       find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
2183 +                          -o -name '[@,#]*' -o -name '*.old' \
2184 +                          -o -name '*.orig' -o -name '*.rej' \
2185 +                          -o -name '*.bak' ')' \
2186 +                          -exec rm -f {} ';'
2187 +
2188 +# Check for smelly exported symbols (not starting with Py/_Py)
2189 +smelly: all
2190 +       nm -p $(LIBRARY) | \
2191 +               sed -n "/ [TDB] /s/.* //p" | grep -v "^_*Py" | sort -u; \
2192 +
2193 +# Find files with funny names
2194 +funny:
2195 +       find $(DISTDIRS) -type d \
2196 +               -o -name '*.[chs]' \
2197 +               -o -name '*.py' \
2198 +               -o -name '*.doc' \
2199 +               -o -name '*.sty' \
2200 +               -o -name '*.bib' \
2201 +               -o -name '*.dat' \
2202 +               -o -name '*.el' \
2203 +               -o -name '*.fd' \
2204 +               -o -name '*.in' \
2205 +               -o -name '*.tex' \
2206 +               -o -name '*,[vpt]' \
2207 +               -o -name 'Setup' \
2208 +               -o -name 'Setup.*' \
2209 +               -o -name README \
2210 +               -o -name Makefile \
2211 +               -o -name ChangeLog \
2212 +               -o -name Repository \
2213 +               -o -name Root \
2214 +               -o -name Entries \
2215 +               -o -name Tag \
2216 +               -o -name tags \
2217 +               -o -name TAGS \
2218 +               -o -name .cvsignore \
2219 +               -o -name MANIFEST \
2220 +               -o -print
2221 +
2222 +# Dependencies
2223 +
2224 +Python/thread.o: @THREADHEADERS@
2225 +
2226 +# Declare targets that aren't real files
2227 +.PHONY: all sharedmods oldsharedmods test quicktest memtest
2228 +.PHONY: install altinstall oldsharedinstall bininstall altbininstall
2229 +.PHONY: maninstall libinstall inclinstall libainstall sharedinstall
2230 +.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
2231 +.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools
2232 +.PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean 
2233 +.PHONY: smelly funny
2234 +
2235 +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
2236 diff -urN Python-2.5.2.orig/Modules/posixmodule.c Python-2.5.2.mingw/Modules/posixmodule.c
2237 --- Python-2.5.2.orig/Modules/posixmodule.c     2008-10-06 18:43:25.000000000 +0100
2238 +++ Python-2.5.2.mingw/Modules/posixmodule.c    2008-10-07 11:50:18.000000000 +0100
2239 @@ -131,6 +131,16 @@
2240  #define HAVE_FSYNC     1
2241  #define fsync _commit
2242  #else
2243 +#ifdef __MINGW32__     /* MinGW compiler */
2244 +#define HAVE_GETCWD     1
2245 +#define HAVE_SPAWNV    1
2246 +#define HAVE_EXECV      1
2247 +#define HAVE_PIPE       1
2248 +#define HAVE_POPEN      1
2249 +#define HAVE_SYSTEM    1
2250 +#define HAVE_CWAIT     1
2251 +#define HAVE_FSYNC     1
2252 +#define fsync _commit
2253  #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
2254  /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
2255  #else                  /* all other compilers */
2256 @@ -156,6 +166,7 @@
2257  #define HAVE_WAIT       1
2258  #define HAVE_TTYNAME   1
2259  #endif  /* PYOS_OS2 && PYCC_GCC && __VMS */
2260 +#endif  /* __MINGW32__ */
2261  #endif  /* _MSC_VER */
2262  #endif  /* __BORLANDC__ */
2263  #endif  /* ! __WATCOMC__ || __QNX__ */
2264 @@ -173,7 +184,7 @@
2265  #if defined(PYCC_VACPP)
2266  extern int mkdir(char *);
2267  #else
2268 -#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
2269 +#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__)) && !defined(__QNX__)
2270  extern int mkdir(const char *);
2271  #else
2272  extern int mkdir(const char *, mode_t);
2273 @@ -189,9 +200,13 @@
2274  #ifdef __BORLANDC__
2275  extern int chmod(const char *, int);
2276  #else
2277 +#ifndef __MINGW32__
2278  extern int chmod(const char *, mode_t);
2279  #endif
2280 +#endif
2281 +#ifndef __MINGW32__
2282  extern int chown(const char *, uid_t, gid_t);
2283 +#endif
2284  extern char *getcwd(char *, int);
2285  extern char *strerror(int);
2286  extern int link(const char *, const char *);
2287 @@ -252,7 +267,7 @@
2288  #endif
2289  #endif
2290  
2291 -#ifdef _MSC_VER
2292 +#if defined(_MSC_VER) || defined(__MINGW32__)
2293  #ifdef HAVE_DIRECT_H
2294  #include <direct.h>
2295  #endif
2296 @@ -345,7 +360,7 @@
2297  */
2298  #include <crt_externs.h>
2299  static char **environ;
2300 -#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
2301 +#elif !defined(_MSC_VER) && !defined(__MINGW32__) && ( !defined(__WATCOMC__) || defined(__QNX__) )
2302  extern char **environ;
2303  #endif /* !_MSC_VER */
2304  
2305 @@ -2328,7 +2343,7 @@
2306                               Py_FileSystemDefaultEncoding, &path, &mode))
2307                 return NULL;
2308         Py_BEGIN_ALLOW_THREADS
2309 -#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2310 +#if ( defined(__MINGW32__) || defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2311         res = mkdir(path);
2312  #else
2313         res = mkdir(path, mode);
2314 @@ -7972,7 +7987,7 @@
2315  }
2316  #endif
2317  
2318 -#ifdef MS_WINDOWS
2319 +#if defined(MS_WINDOWS) && !defined(__MINGW32__)
2320  
2321  PyDoc_STRVAR(win32_urandom__doc__,
2322  "urandom(n) -> str\n\n\
2323 @@ -8371,9 +8386,9 @@
2324  #ifdef HAVE_GETLOADAVG
2325         {"getloadavg",  posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
2326  #endif
2327 - #ifdef MS_WINDOWS
2328 +#if defined(MS_WINDOWS) && !defined(__MINGW32__)
2329         {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
2330 - #endif
2331 +#endif
2332   #ifdef __VMS
2333         {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
2334   #endif
2335 @@ -8653,7 +8668,7 @@
2336  }
2337  
2338  
2339 -#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
2340 +#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
2341  #define INITFUNC initnt
2342  #define MODNAME "nt"
2343  
2344 diff -urN Python-2.5.2.orig/Modules/posixmodule.c~ Python-2.5.2.mingw/Modules/posixmodule.c~
2345 --- Python-2.5.2.orig/Modules/posixmodule.c~    1970-01-01 01:00:00.000000000 +0100
2346 +++ Python-2.5.2.mingw/Modules/posixmodule.c~   2008-10-06 18:43:25.000000000 +0100
2347 @@ -0,0 +1,8764 @@
2348 +
2349 +/* POSIX module implementation */
2350 +
2351 +/* This file is also used for Windows NT/MS-Win and OS/2.  In that case the
2352 +   module actually calls itself 'nt' or 'os2', not 'posix', and a few
2353 +   functions are either unimplemented or implemented differently.  The source
2354 +   assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
2355 +   of the compiler used.  Different compilers define their own feature
2356 +   test macro, e.g. '__BORLANDC__' or '_MSC_VER'.  For OS/2, the compiler
2357 +   independent macro PYOS_OS2 should be defined.  On OS/2 the default
2358 +   compiler is assumed to be IBM's VisualAge C++ (VACPP).  PYCC_GCC is used
2359 +   as the compiler specific macro for the EMX port of gcc to OS/2. */
2360 +
2361 +/* See also ../Dos/dosmodule.c */
2362 +
2363 +#ifdef __APPLE__
2364 +   /*
2365 +    * Step 1 of support for weak-linking a number of symbols existing on 
2366 +    * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
2367 +    * at the end of this file for more information.
2368 +    */
2369 +#  pragma weak lchown
2370 +#  pragma weak statvfs
2371 +#  pragma weak fstatvfs
2372 +
2373 +#endif /* __APPLE__ */
2374 +
2375 +#define PY_SSIZE_T_CLEAN
2376 +
2377 +#include "Python.h"
2378 +#include "structseq.h"
2379 +
2380 +#if defined(__VMS)
2381 +#    include <unixio.h>
2382 +#endif /* defined(__VMS) */
2383 +
2384 +#ifdef __cplusplus
2385 +extern "C" {
2386 +#endif
2387 +
2388 +PyDoc_STRVAR(posix__doc__,
2389 +"This module provides access to operating system functionality that is\n\
2390 +standardized by the C Standard and the POSIX standard (a thinly\n\
2391 +disguised Unix interface).  Refer to the library manual and\n\
2392 +corresponding Unix manual entries for more information on calls.");
2393 +
2394 +#ifndef Py_USING_UNICODE
2395 +/* This is used in signatures of functions. */
2396 +#define Py_UNICODE void
2397 +#endif
2398 +
2399 +#if defined(PYOS_OS2)
2400 +#define  INCL_DOS
2401 +#define  INCL_DOSERRORS
2402 +#define  INCL_DOSPROCESS
2403 +#define  INCL_NOPMAPI
2404 +#include <os2.h>
2405 +#if defined(PYCC_GCC)
2406 +#include <ctype.h>
2407 +#include <io.h>
2408 +#include <stdio.h>
2409 +#include <process.h>
2410 +#endif
2411 +#include "osdefs.h"
2412 +#endif
2413 +
2414 +#ifdef HAVE_SYS_TYPES_H
2415 +#include <sys/types.h>
2416 +#endif /* HAVE_SYS_TYPES_H */
2417 +
2418 +#ifdef HAVE_SYS_STAT_H
2419 +#include <sys/stat.h>
2420 +#endif /* HAVE_SYS_STAT_H */
2421 +
2422 +#ifdef HAVE_SYS_WAIT_H
2423 +#include <sys/wait.h>          /* For WNOHANG */
2424 +#endif
2425 +
2426 +#ifdef HAVE_SIGNAL_H
2427 +#include <signal.h>
2428 +#endif
2429 +
2430 +#ifdef HAVE_FCNTL_H
2431 +#include <fcntl.h>
2432 +#endif /* HAVE_FCNTL_H */
2433 +
2434 +#ifdef HAVE_GRP_H
2435 +#include <grp.h>
2436 +#endif
2437 +
2438 +#ifdef HAVE_SYSEXITS_H
2439 +#include <sysexits.h>
2440 +#endif /* HAVE_SYSEXITS_H */
2441 +
2442 +#ifdef HAVE_SYS_LOADAVG_H
2443 +#include <sys/loadavg.h>
2444 +#endif
2445 +
2446 +/* Various compilers have only certain posix functions */
2447 +/* XXX Gosh I wish these were all moved into pyconfig.h */
2448 +#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2449 +#include <process.h>
2450 +#else
2451 +#if defined(__WATCOMC__) && !defined(__QNX__)          /* Watcom compiler */
2452 +#define HAVE_GETCWD     1
2453 +#define HAVE_OPENDIR    1
2454 +#define HAVE_SYSTEM    1
2455 +#if defined(__OS2__)
2456 +#define HAVE_EXECV      1
2457 +#define HAVE_WAIT       1
2458 +#endif
2459 +#include <process.h>
2460 +#else
2461 +#ifdef __BORLANDC__            /* Borland compiler */
2462 +#define HAVE_EXECV      1
2463 +#define HAVE_GETCWD     1
2464 +#define HAVE_OPENDIR    1
2465 +#define HAVE_PIPE       1
2466 +#define HAVE_POPEN      1
2467 +#define HAVE_SYSTEM    1
2468 +#define HAVE_WAIT       1
2469 +#else
2470 +#ifdef _MSC_VER                /* Microsoft compiler */
2471 +#define HAVE_GETCWD     1
2472 +#define HAVE_SPAWNV    1
2473 +#define HAVE_EXECV      1
2474 +#define HAVE_PIPE       1
2475 +#define HAVE_POPEN      1
2476 +#define HAVE_SYSTEM    1
2477 +#define HAVE_CWAIT     1
2478 +#define HAVE_FSYNC     1
2479 +#define fsync _commit
2480 +#else
2481 +#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
2482 +/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
2483 +#else                  /* all other compilers */
2484 +/* Unix functions that the configure script doesn't check for */
2485 +#define HAVE_EXECV      1
2486 +#define HAVE_FORK       1
2487 +#if defined(__USLC__) && defined(__SCO_VERSION__)      /* SCO UDK Compiler */
2488 +#define HAVE_FORK1      1
2489 +#endif
2490 +#define HAVE_GETCWD     1
2491 +#define HAVE_GETEGID    1
2492 +#define HAVE_GETEUID    1
2493 +#define HAVE_GETGID     1
2494 +#define HAVE_GETPPID    1
2495 +#define HAVE_GETUID     1
2496 +#define HAVE_KILL       1
2497 +#define HAVE_OPENDIR    1
2498 +#define HAVE_PIPE       1
2499 +#ifndef __rtems__
2500 +#define HAVE_POPEN      1
2501 +#endif
2502 +#define HAVE_SYSTEM    1
2503 +#define HAVE_WAIT       1
2504 +#define HAVE_TTYNAME   1
2505 +#endif  /* PYOS_OS2 && PYCC_GCC && __VMS */
2506 +#endif  /* _MSC_VER */
2507 +#endif  /* __BORLANDC__ */
2508 +#endif  /* ! __WATCOMC__ || __QNX__ */
2509 +#endif /* ! __IBMC__ */
2510 +
2511 +#ifndef _MSC_VER
2512 +
2513 +#if defined(__sgi)&&_COMPILER_VERSION>=700
2514 +/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
2515 +   (default) */
2516 +extern char        *ctermid_r(char *);
2517 +#endif
2518 +
2519 +#ifndef HAVE_UNISTD_H
2520 +#if defined(PYCC_VACPP)
2521 +extern int mkdir(char *);
2522 +#else
2523 +#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
2524 +extern int mkdir(const char *);
2525 +#else
2526 +extern int mkdir(const char *, mode_t);
2527 +#endif
2528 +#endif
2529 +#if defined(__IBMC__) || defined(__IBMCPP__)
2530 +extern int chdir(char *);
2531 +extern int rmdir(char *);
2532 +#else
2533 +extern int chdir(const char *);
2534 +extern int rmdir(const char *);
2535 +#endif
2536 +#ifdef __BORLANDC__
2537 +extern int chmod(const char *, int);
2538 +#else
2539 +extern int chmod(const char *, mode_t);
2540 +#endif
2541 +extern int chown(const char *, uid_t, gid_t);
2542 +extern char *getcwd(char *, int);
2543 +extern char *strerror(int);
2544 +extern int link(const char *, const char *);
2545 +extern int rename(const char *, const char *);
2546 +extern int stat(const char *, struct stat *);
2547 +extern int unlink(const char *);
2548 +extern int pclose(FILE *);
2549 +#ifdef HAVE_SYMLINK
2550 +extern int symlink(const char *, const char *);
2551 +#endif /* HAVE_SYMLINK */
2552 +#ifdef HAVE_LSTAT
2553 +extern int lstat(const char *, struct stat *);
2554 +#endif /* HAVE_LSTAT */
2555 +#endif /* !HAVE_UNISTD_H */
2556 +
2557 +#endif /* !_MSC_VER */
2558 +
2559 +#ifdef HAVE_UTIME_H
2560 +#include <utime.h>
2561 +#endif /* HAVE_UTIME_H */
2562 +
2563 +#ifdef HAVE_SYS_UTIME_H
2564 +#include <sys/utime.h>
2565 +#define HAVE_UTIME_H /* pretend we do for the rest of this file */
2566 +#endif /* HAVE_SYS_UTIME_H */
2567 +
2568 +#ifdef HAVE_SYS_TIMES_H
2569 +#include <sys/times.h>
2570 +#endif /* HAVE_SYS_TIMES_H */
2571 +
2572 +#ifdef HAVE_SYS_PARAM_H
2573 +#include <sys/param.h>
2574 +#endif /* HAVE_SYS_PARAM_H */
2575 +
2576 +#ifdef HAVE_SYS_UTSNAME_H
2577 +#include <sys/utsname.h>
2578 +#endif /* HAVE_SYS_UTSNAME_H */
2579 +
2580 +#ifdef HAVE_DIRENT_H
2581 +#include <dirent.h>
2582 +#define NAMLEN(dirent) strlen((dirent)->d_name)
2583 +#else
2584 +#if defined(__WATCOMC__) && !defined(__QNX__)
2585 +#include <direct.h>
2586 +#define NAMLEN(dirent) strlen((dirent)->d_name)
2587 +#else
2588 +#define dirent direct
2589 +#define NAMLEN(dirent) (dirent)->d_namlen
2590 +#endif
2591 +#ifdef HAVE_SYS_NDIR_H
2592 +#include <sys/ndir.h>
2593 +#endif
2594 +#ifdef HAVE_SYS_DIR_H
2595 +#include <sys/dir.h>
2596 +#endif
2597 +#ifdef HAVE_NDIR_H
2598 +#include <ndir.h>
2599 +#endif
2600 +#endif
2601 +
2602 +#ifdef _MSC_VER
2603 +#ifdef HAVE_DIRECT_H
2604 +#include <direct.h>
2605 +#endif
2606 +#ifdef HAVE_IO_H
2607 +#include <io.h>
2608 +#endif
2609 +#ifdef HAVE_PROCESS_H
2610 +#include <process.h>
2611 +#endif
2612 +#include "osdefs.h"
2613 +#define _WIN32_WINNT 0x0400      /* Needed for CryptoAPI on some systems */
2614 +#include <windows.h>
2615 +#include <shellapi.h>  /* for ShellExecute() */
2616 +#define popen  _popen
2617 +#define pclose _pclose
2618 +#endif /* _MSC_VER */
2619 +
2620 +#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2621 +#include <io.h>
2622 +#endif /* OS2 */
2623 +
2624 +#ifndef MAXPATHLEN
2625 +#if defined(PATH_MAX) && PATH_MAX > 1024
2626 +#define MAXPATHLEN PATH_MAX
2627 +#else
2628 +#define MAXPATHLEN 1024
2629 +#endif
2630 +#endif /* MAXPATHLEN */
2631 +
2632 +#ifdef UNION_WAIT
2633 +/* Emulate some macros on systems that have a union instead of macros */
2634 +
2635 +#ifndef WIFEXITED
2636 +#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
2637 +#endif
2638 +
2639 +#ifndef WEXITSTATUS
2640 +#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
2641 +#endif
2642 +
2643 +#ifndef WTERMSIG
2644 +#define WTERMSIG(u_wait) ((u_wait).w_termsig)
2645 +#endif
2646 +
2647 +#define WAIT_TYPE union wait
2648 +#define WAIT_STATUS_INT(s) (s.w_status)
2649 +
2650 +#else /* !UNION_WAIT */
2651 +#define WAIT_TYPE int
2652 +#define WAIT_STATUS_INT(s) (s)
2653 +#endif /* UNION_WAIT */
2654 +
2655 +/* Don't use the "_r" form if we don't need it (also, won't have a
2656 +   prototype for it, at least on Solaris -- maybe others as well?). */
2657 +#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
2658 +#define USE_CTERMID_R
2659 +#endif
2660 +
2661 +#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
2662 +#define USE_TMPNAM_R
2663 +#endif
2664 +
2665 +/* choose the appropriate stat and fstat functions and return structs */
2666 +#undef STAT
2667 +#if defined(MS_WIN64) || defined(MS_WINDOWS)
2668 +#      define STAT win32_stat
2669 +#      define FSTAT win32_fstat
2670 +#      define STRUCT_STAT struct win32_stat
2671 +#else
2672 +#      define STAT stat
2673 +#      define FSTAT fstat
2674 +#      define STRUCT_STAT struct stat
2675 +#endif
2676 +
2677 +#if defined(MAJOR_IN_MKDEV)
2678 +#include <sys/mkdev.h>
2679 +#else
2680 +#if defined(MAJOR_IN_SYSMACROS)
2681 +#include <sys/sysmacros.h>
2682 +#endif
2683 +#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
2684 +#include <sys/mkdev.h>
2685 +#endif
2686 +#endif
2687 +
2688 +/* Return a dictionary corresponding to the POSIX environment table */
2689 +#ifdef WITH_NEXT_FRAMEWORK
2690 +/* On Darwin/MacOSX a shared library or framework has no access to
2691 +** environ directly, we must obtain it with _NSGetEnviron().
2692 +*/
2693 +#include <crt_externs.h>
2694 +static char **environ;
2695 +#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
2696 +extern char **environ;
2697 +#endif /* !_MSC_VER */
2698 +
2699 +static PyObject *
2700 +convertenviron(void)
2701 +{
2702 +       PyObject *d;
2703 +       char **e;
2704 +       d = PyDict_New();
2705 +       if (d == NULL)
2706 +               return NULL;
2707 +#ifdef WITH_NEXT_FRAMEWORK
2708 +       if (environ == NULL)
2709 +               environ = *_NSGetEnviron();
2710 +#endif
2711 +       if (environ == NULL)
2712 +               return d;
2713 +       /* This part ignores errors */
2714 +       for (e = environ; *e != NULL; e++) {
2715 +               PyObject *k;
2716 +               PyObject *v;
2717 +               char *p = strchr(*e, '=');
2718 +               if (p == NULL)
2719 +                       continue;
2720 +               k = PyString_FromStringAndSize(*e, (int)(p-*e));
2721 +               if (k == NULL) {
2722 +                       PyErr_Clear();
2723 +                       continue;
2724 +               }
2725 +               v = PyString_FromString(p+1);
2726 +               if (v == NULL) {
2727 +                       PyErr_Clear();
2728 +                       Py_DECREF(k);
2729 +                       continue;
2730 +               }
2731 +               if (PyDict_GetItem(d, k) == NULL) {
2732 +                       if (PyDict_SetItem(d, k, v) != 0)
2733 +                               PyErr_Clear();
2734 +               }
2735 +               Py_DECREF(k);
2736 +               Py_DECREF(v);
2737 +       }
2738 +#if defined(PYOS_OS2)
2739 +    {
2740 +        APIRET rc;
2741 +        char   buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
2742 +
2743 +        rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
2744 +       if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
2745 +            PyObject *v = PyString_FromString(buffer);
2746 +                   PyDict_SetItemString(d, "BEGINLIBPATH", v);
2747 +            Py_DECREF(v);
2748 +        }
2749 +        rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
2750 +        if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
2751 +            PyObject *v = PyString_FromString(buffer);
2752 +                   PyDict_SetItemString(d, "ENDLIBPATH", v);
2753 +            Py_DECREF(v);
2754 +        }
2755 +    }
2756 +#endif
2757 +       return d;
2758 +}
2759 +
2760 +
2761 +/* Set a POSIX-specific error from errno, and return NULL */
2762 +
2763 +static PyObject *
2764 +posix_error(void)
2765 +{
2766 +       return PyErr_SetFromErrno(PyExc_OSError);
2767 +}
2768 +static PyObject *
2769 +posix_error_with_filename(char* name)
2770 +{
2771 +       return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
2772 +}
2773 +
2774 +#ifdef Py_WIN_WIDE_FILENAMES
2775 +static PyObject *
2776 +posix_error_with_unicode_filename(Py_UNICODE* name)
2777 +{
2778 +       return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
2779 +}
2780 +#endif /* Py_WIN_WIDE_FILENAMES */
2781 +
2782 +
2783 +static PyObject *
2784 +posix_error_with_allocated_filename(char* name)
2785 +{
2786 +       PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
2787 +       PyMem_Free(name);
2788 +       return rc;
2789 +}
2790 +
2791 +#ifdef MS_WINDOWS
2792 +static PyObject *
2793 +win32_error(char* function, char* filename)
2794 +{
2795 +       /* XXX We should pass the function name along in the future.
2796 +          (_winreg.c also wants to pass the function name.)
2797 +          This would however require an additional param to the
2798 +          Windows error object, which is non-trivial.
2799 +       */
2800 +       errno = GetLastError();
2801 +       if (filename)
2802 +               return PyErr_SetFromWindowsErrWithFilename(errno, filename);
2803 +       else
2804 +               return PyErr_SetFromWindowsErr(errno);
2805 +}
2806 +
2807 +#ifdef Py_WIN_WIDE_FILENAMES
2808 +static PyObject *
2809 +win32_error_unicode(char* function, Py_UNICODE* filename)
2810 +{
2811 +       /* XXX - see win32_error for comments on 'function' */
2812 +       errno = GetLastError();
2813 +       if (filename)
2814 +               return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
2815 +       else
2816 +               return PyErr_SetFromWindowsErr(errno);
2817 +}
2818 +
2819 +static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
2820 +{
2821 +}
2822 +
2823 +/* Function suitable for O& conversion */
2824 +static int
2825 +convert_to_unicode(PyObject *arg, void* _param)
2826 +{
2827 +       PyObject **param = (PyObject**)_param;
2828 +       if (PyUnicode_CheckExact(arg)) {
2829 +               Py_INCREF(arg);
2830 +               *param = arg;
2831 +       } 
2832 +       else if (PyUnicode_Check(arg)) {
2833 +               /* For a Unicode subtype that's not a Unicode object,
2834 +                  return a true Unicode object with the same data. */
2835 +               *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
2836 +                                              PyUnicode_GET_SIZE(arg));
2837 +               return *param != NULL;
2838 +       }
2839 +       else
2840 +               *param = PyUnicode_FromEncodedObject(arg,
2841 +                                                    Py_FileSystemDefaultEncoding,
2842 +                                                    "strict");
2843 +       return (*param) != NULL;
2844 +}
2845 +
2846 +#endif /* Py_WIN_WIDE_FILENAMES */
2847 +
2848 +#endif
2849 +
2850 +#if defined(PYOS_OS2)
2851 +/**********************************************************************
2852 + *         Helper Function to Trim and Format OS/2 Messages
2853 + **********************************************************************/
2854 +    static void
2855 +os2_formatmsg(char *msgbuf, int msglen, char *reason)
2856 +{
2857 +    msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
2858 +
2859 +    if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
2860 +        char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
2861 +
2862 +        while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
2863 +            *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
2864 +    }
2865 +
2866 +    /* Add Optional Reason Text */
2867 +    if (reason) {
2868 +        strcat(msgbuf, " : ");
2869 +        strcat(msgbuf, reason);
2870 +    }
2871 +}
2872 +
2873 +/**********************************************************************
2874 + *             Decode an OS/2 Operating System Error Code
2875 + *
2876 + * A convenience function to lookup an OS/2 error code and return a
2877 + * text message we can use to raise a Python exception.
2878 + *
2879 + * Notes:
2880 + *   The messages for errors returned from the OS/2 kernel reside in
2881 + *   the file OSO001.MSG in the \OS2 directory hierarchy.
2882 + *
2883 + **********************************************************************/
2884 +    static char *
2885 +os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
2886 +{
2887 +    APIRET rc;
2888 +    ULONG  msglen;
2889 +
2890 +    /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
2891 +    Py_BEGIN_ALLOW_THREADS
2892 +    rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
2893 +                       errorcode, "oso001.msg", &msglen);
2894 +    Py_END_ALLOW_THREADS
2895 +
2896 +    if (rc == NO_ERROR)
2897 +        os2_formatmsg(msgbuf, msglen, reason);
2898 +    else
2899 +        PyOS_snprintf(msgbuf, msgbuflen,
2900 +                     "unknown OS error #%d", errorcode);
2901 +
2902 +    return msgbuf;
2903 +}
2904 +
2905 +/* Set an OS/2-specific error and return NULL.  OS/2 kernel
2906 +   errors are not in a global variable e.g. 'errno' nor are
2907 +   they congruent with posix error numbers. */
2908 +
2909 +static PyObject * os2_error(int code)
2910 +{
2911 +    char text[1024];
2912 +    PyObject *v;
2913 +
2914 +    os2_strerror(text, sizeof(text), code, "");
2915 +
2916 +    v = Py_BuildValue("(is)", code, text);
2917 +    if (v != NULL) {
2918 +        PyErr_SetObject(PyExc_OSError, v);
2919 +        Py_DECREF(v);
2920 +    }
2921 +    return NULL; /* Signal to Python that an Exception is Pending */
2922 +}
2923 +
2924 +#endif /* OS2 */
2925 +
2926 +/* POSIX generic methods */
2927 +
2928 +static PyObject *
2929 +posix_fildes(PyObject *fdobj, int (*func)(int))
2930 +{
2931 +       int fd;
2932 +       int res;
2933 +       fd = PyObject_AsFileDescriptor(fdobj);
2934 +       if (fd < 0)
2935 +               return NULL;
2936 +       Py_BEGIN_ALLOW_THREADS
2937 +       res = (*func)(fd);
2938 +       Py_END_ALLOW_THREADS
2939 +       if (res < 0)
2940 +               return posix_error();
2941 +       Py_INCREF(Py_None);
2942 +       return Py_None;
2943 +}
2944 +
2945 +#ifdef Py_WIN_WIDE_FILENAMES
2946 +static int
2947 +unicode_file_names(void)
2948 +{
2949 +       static int canusewide = -1;
2950 +       if (canusewide == -1) {
2951 +               /* As per doc for ::GetVersion(), this is the correct test for
2952 +                  the Windows NT family. */
2953 +               canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
2954 +       }
2955 +       return canusewide;
2956 +}
2957 +#endif
2958 +
2959 +static PyObject *
2960 +posix_1str(PyObject *args, char *format, int (*func)(const char*))
2961 +{
2962 +       char *path1 = NULL;
2963 +       int res;
2964 +       if (!PyArg_ParseTuple(args, format,
2965 +                             Py_FileSystemDefaultEncoding, &path1))
2966 +               return NULL;
2967 +       Py_BEGIN_ALLOW_THREADS
2968 +       res = (*func)(path1);
2969 +       Py_END_ALLOW_THREADS
2970 +       if (res < 0)
2971 +               return posix_error_with_allocated_filename(path1);
2972 +       PyMem_Free(path1);
2973 +       Py_INCREF(Py_None);
2974 +       return Py_None;
2975 +}
2976 +
2977 +static PyObject *
2978 +posix_2str(PyObject *args,
2979 +          char *format,
2980 +          int (*func)(const char *, const char *))
2981 +{
2982 +       char *path1 = NULL, *path2 = NULL;
2983 +       int res;
2984 +       if (!PyArg_ParseTuple(args, format,
2985 +                             Py_FileSystemDefaultEncoding, &path1,
2986 +                             Py_FileSystemDefaultEncoding, &path2))
2987 +               return NULL;
2988 +       Py_BEGIN_ALLOW_THREADS
2989 +       res = (*func)(path1, path2);
2990 +       Py_END_ALLOW_THREADS
2991 +       PyMem_Free(path1);
2992 +       PyMem_Free(path2);
2993 +       if (res != 0)
2994 +               /* XXX how to report both path1 and path2??? */
2995 +               return posix_error();
2996 +       Py_INCREF(Py_None);
2997 +       return Py_None;
2998 +}
2999 +
3000 +#ifdef Py_WIN_WIDE_FILENAMES
3001 +static PyObject*
3002 +win32_1str(PyObject* args, char* func, 
3003 +          char* format, BOOL (__stdcall *funcA)(LPCSTR), 
3004 +          char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
3005 +{
3006 +       PyObject *uni;
3007 +       char *ansi;
3008 +       BOOL result;
3009 +       if (unicode_file_names()) {
3010 +               if (!PyArg_ParseTuple(args, wformat, &uni))
3011 +                       PyErr_Clear();
3012 +               else {
3013 +                       Py_BEGIN_ALLOW_THREADS
3014 +                       result = funcW(PyUnicode_AsUnicode(uni));
3015 +                       Py_END_ALLOW_THREADS
3016 +                       if (!result)
3017 +                               return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
3018 +                       Py_INCREF(Py_None);
3019 +                       return Py_None;
3020 +               }
3021 +       }
3022 +       if (!PyArg_ParseTuple(args, format, &ansi))
3023 +               return NULL;
3024 +       Py_BEGIN_ALLOW_THREADS
3025 +       result = funcA(ansi);
3026 +       Py_END_ALLOW_THREADS
3027 +       if (!result)
3028 +               return win32_error(func, ansi);
3029 +       Py_INCREF(Py_None);
3030 +       return Py_None;
3031 +
3032 +}
3033 +
3034 +/* This is a reimplementation of the C library's chdir function,
3035 +   but one that produces Win32 errors instead of DOS error codes.
3036 +   chdir is essentially a wrapper around SetCurrentDirectory; however,
3037 +   it also needs to set "magic" environment variables indicating
3038 +   the per-drive current directory, which are of the form =<drive>: */
3039 +BOOL __stdcall
3040 +win32_chdir(LPCSTR path)
3041 +{
3042 +       char new_path[MAX_PATH+1];
3043 +       int result;
3044 +       char env[4] = "=x:";
3045 +
3046 +       if(!SetCurrentDirectoryA(path))
3047 +               return FALSE;
3048 +       result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
3049 +       if (!result)
3050 +               return FALSE;
3051 +       /* In the ANSI API, there should not be any paths longer
3052 +          than MAX_PATH. */
3053 +       assert(result <= MAX_PATH+1);
3054 +       if (strncmp(new_path, "\\\\", 2) == 0 ||
3055 +           strncmp(new_path, "//", 2) == 0)
3056 +           /* UNC path, nothing to do. */
3057 +           return TRUE;
3058 +       env[1] = new_path[0];
3059 +       return SetEnvironmentVariableA(env, new_path);
3060 +}
3061 +
3062 +/* The Unicode version differs from the ANSI version
3063 +   since the current directory might exceed MAX_PATH characters */
3064 +BOOL __stdcall
3065 +win32_wchdir(LPCWSTR path)
3066 +{
3067 +       wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
3068 +       int result;
3069 +       wchar_t env[4] = L"=x:";
3070 +
3071 +       if(!SetCurrentDirectoryW(path))
3072 +               return FALSE;
3073 +       result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
3074 +       if (!result)
3075 +               return FALSE;
3076 +       if (result > MAX_PATH+1) {
3077 +               new_path = malloc(result);
3078 +               if (!new_path) {
3079 +                       SetLastError(ERROR_OUTOFMEMORY);
3080 +                       return FALSE;
3081 +               }
3082 +       }
3083 +       if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
3084 +           wcsncmp(new_path, L"//", 2) == 0)
3085 +           /* UNC path, nothing to do. */
3086 +           return TRUE;
3087 +       env[1] = new_path[0];
3088 +       result = SetEnvironmentVariableW(env, new_path);
3089 +       if (new_path != _new_path)
3090 +               free(new_path);
3091 +       return result;
3092 +}
3093 +#endif
3094 +
3095 +#ifdef MS_WINDOWS
3096 +/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
3097 +   - time stamps are restricted to second resolution
3098 +   - file modification times suffer from forth-and-back conversions between
3099 +     UTC and local time
3100 +   Therefore, we implement our own stat, based on the Win32 API directly.
3101 +*/
3102 +#define HAVE_STAT_NSEC 1 
3103 +
3104 +struct win32_stat{
3105 +    int st_dev;
3106 +    __int64 st_ino;
3107 +    unsigned short st_mode;
3108 +    int st_nlink;
3109 +    int st_uid;
3110 +    int st_gid;
3111 +    int st_rdev;
3112 +    __int64 st_size;
3113 +    int st_atime;
3114 +    int st_atime_nsec;
3115 +    int st_mtime;
3116 +    int st_mtime_nsec;
3117 +    int st_ctime;
3118 +    int st_ctime_nsec;
3119 +};
3120 +
3121 +static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
3122 +
3123 +static void
3124 +FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
3125 +{
3126 +       /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
3127 +       /* Cannot simply cast and dereference in_ptr, 
3128 +          since it might not be aligned properly */
3129 +       __int64 in;
3130 +       memcpy(&in, in_ptr, sizeof(in));
3131 +       *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
3132 +       /* XXX Win32 supports time stamps past 2038; we currently don't */
3133 +       *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
3134 +}
3135 +
3136 +static void
3137 +time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
3138 +{
3139 +       /* XXX endianness */
3140 +       __int64 out;
3141 +       out = time_in + secs_between_epochs;
3142 +       out = out * 10000000 + nsec_in / 100;
3143 +       memcpy(out_ptr, &out, sizeof(out));
3144 +}
3145 +
3146 +/* Below, we *know* that ugo+r is 0444 */
3147 +#if _S_IREAD != 0400
3148 +#error Unsupported C library
3149 +#endif
3150 +static int
3151 +attributes_to_mode(DWORD attr)
3152 +{
3153 +       int m = 0;
3154 +       if (attr & FILE_ATTRIBUTE_DIRECTORY)
3155 +               m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
3156 +       else
3157 +               m |= _S_IFREG;
3158 +       if (attr & FILE_ATTRIBUTE_READONLY)
3159 +               m |= 0444;
3160 +       else
3161 +               m |= 0666;
3162 +       return m;
3163 +}
3164 +
3165 +static int
3166 +attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
3167 +{
3168 +       memset(result, 0, sizeof(*result));
3169 +       result->st_mode = attributes_to_mode(info->dwFileAttributes);
3170 +       result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
3171 +       FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
3172 +       FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
3173 +       FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
3174 +
3175 +       return 0;
3176 +}
3177 +
3178 +/* Emulate GetFileAttributesEx[AW] on Windows 95 */
3179 +static int checked = 0;
3180 +static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
3181 +static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
3182 +static void
3183 +check_gfax()
3184 +{
3185 +       HINSTANCE hKernel32;
3186 +       if (checked)
3187 +           return;
3188 +       checked = 1;
3189 +       hKernel32 = GetModuleHandle("KERNEL32");
3190 +       *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
3191 +       *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
3192 +}
3193 +
3194 +static BOOL
3195 +attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
3196 +{
3197 +       HANDLE hFindFile;
3198 +       WIN32_FIND_DATAA FileData;
3199 +       hFindFile = FindFirstFileA(pszFile, &FileData);
3200 +       if (hFindFile == INVALID_HANDLE_VALUE)
3201 +               return FALSE;
3202 +       FindClose(hFindFile);
3203 +       pfad->dwFileAttributes = FileData.dwFileAttributes;
3204 +       pfad->ftCreationTime   = FileData.ftCreationTime;
3205 +       pfad->ftLastAccessTime = FileData.ftLastAccessTime;
3206 +       pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
3207 +       pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
3208 +       pfad->nFileSizeLow     = FileData.nFileSizeLow;
3209 +       return TRUE;
3210 +}
3211 +
3212 +static BOOL
3213 +attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
3214 +{
3215 +       HANDLE hFindFile;
3216 +       WIN32_FIND_DATAW FileData;
3217 +       hFindFile = FindFirstFileW(pszFile, &FileData);
3218 +       if (hFindFile == INVALID_HANDLE_VALUE)
3219 +               return FALSE;
3220 +       FindClose(hFindFile);
3221 +       pfad->dwFileAttributes = FileData.dwFileAttributes;
3222 +       pfad->ftCreationTime   = FileData.ftCreationTime;
3223 +       pfad->ftLastAccessTime = FileData.ftLastAccessTime;
3224 +       pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
3225 +       pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
3226 +       pfad->nFileSizeLow     = FileData.nFileSizeLow;
3227 +       return TRUE;
3228 +}
3229 +
3230 +static BOOL WINAPI
3231 +Py_GetFileAttributesExA(LPCSTR pszFile, 
3232 +                      GET_FILEEX_INFO_LEVELS level,
3233 +                       LPVOID pv)
3234 +{
3235 +       BOOL result;
3236 +       LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
3237 +       /* First try to use the system's implementation, if that is
3238 +          available and either succeeds to gives an error other than
3239 +          that it isn't implemented. */
3240 +       check_gfax();
3241 +       if (gfaxa) {
3242 +               result = gfaxa(pszFile, level, pv);
3243 +               if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
3244 +                       return result;
3245 +       }
3246 +       /* It's either not present, or not implemented.
3247 +          Emulate using FindFirstFile. */
3248 +       if (level != GetFileExInfoStandard) {
3249 +               SetLastError(ERROR_INVALID_PARAMETER);
3250 +               return FALSE;
3251 +       }
3252 +       /* Use GetFileAttributes to validate that the file name
3253 +          does not contain wildcards (which FindFirstFile would
3254 +          accept). */
3255 +       if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
3256 +               return FALSE;
3257 +       return attributes_from_dir(pszFile, pfad);
3258 +}
3259 +
3260 +static BOOL WINAPI
3261 +Py_GetFileAttributesExW(LPCWSTR pszFile, 
3262 +                      GET_FILEEX_INFO_LEVELS level,
3263 +                       LPVOID pv)
3264 +{
3265 +       BOOL result;
3266 +       LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
3267 +       /* First try to use the system's implementation, if that is
3268 +          available and either succeeds to gives an error other than
3269 +          that it isn't implemented. */
3270 +       check_gfax();
3271 +       if (gfaxa) {
3272 +               result = gfaxw(pszFile, level, pv);
3273 +               if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
3274 +                       return result;
3275 +       }
3276 +       /* It's either not present, or not implemented.
3277 +          Emulate using FindFirstFile. */
3278 +       if (level != GetFileExInfoStandard) {
3279 +               SetLastError(ERROR_INVALID_PARAMETER);
3280 +               return FALSE;
3281 +       }
3282 +       /* Use GetFileAttributes to validate that the file name
3283 +          does not contain wildcards (which FindFirstFile would
3284 +          accept). */
3285 +       if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
3286 +               return FALSE;
3287 +       return attributes_from_dir_w(pszFile, pfad);
3288 +}
3289 +
3290 +static int 
3291 +win32_stat(const char* path, struct win32_stat *result)
3292 +{
3293 +       WIN32_FILE_ATTRIBUTE_DATA info;
3294 +       int code;
3295 +       char *dot;
3296 +       /* XXX not supported on Win95 and NT 3.x */
3297 +       if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
3298 +               if (GetLastError() != ERROR_SHARING_VIOLATION) {
3299 +                       /* Protocol violation: we explicitly clear errno, instead of
3300 +                          setting it to a POSIX error. Callers should use GetLastError. */
3301 +                       errno = 0;
3302 +                       return -1;
3303 +               } else {
3304 +                       /* Could not get attributes on open file. Fall back to
3305 +                          reading the directory. */
3306 +                       if (!attributes_from_dir(path, &info)) {
3307 +                               /* Very strange. This should not fail now */
3308 +                               errno = 0;
3309 +                               return -1;
3310 +                       }
3311 +               }
3312 +       }
3313 +       code = attribute_data_to_stat(&info, result);
3314 +       if (code != 0)
3315 +               return code;
3316 +       /* Set S_IFEXEC if it is an .exe, .bat, ... */
3317 +       dot = strrchr(path, '.');
3318 +       if (dot) {
3319 +               if (stricmp(dot, ".bat") == 0 ||
3320 +               stricmp(dot, ".cmd") == 0 ||
3321 +               stricmp(dot, ".exe") == 0 ||
3322 +               stricmp(dot, ".com") == 0)
3323 +               result->st_mode |= 0111;
3324 +       }
3325 +       return code;
3326 +}
3327 +
3328 +static int 
3329 +win32_wstat(const wchar_t* path, struct win32_stat *result)
3330 +{
3331 +       int code;
3332 +       const wchar_t *dot;
3333 +       WIN32_FILE_ATTRIBUTE_DATA info;
3334 +       /* XXX not supported on Win95 and NT 3.x */
3335 +       if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
3336 +               if (GetLastError() != ERROR_SHARING_VIOLATION) {
3337 +                       /* Protocol violation: we explicitly clear errno, instead of
3338 +                          setting it to a POSIX error. Callers should use GetLastError. */
3339 +                       errno = 0;
3340 +                       return -1;
3341 +               } else {
3342 +                       /* Could not get attributes on open file. Fall back to
3343 +                          reading the directory. */
3344 +                       if (!attributes_from_dir_w(path, &info)) {
3345 +                               /* Very strange. This should not fail now */
3346 +                               errno = 0;
3347 +                               return -1;
3348 +                       }
3349 +               }
3350 +       }
3351 +       code = attribute_data_to_stat(&info, result);
3352 +       if (code < 0)
3353 +               return code;
3354 +       /* Set IFEXEC if it is an .exe, .bat, ... */
3355 +       dot = wcsrchr(path, '.');
3356 +       if (dot) {
3357 +               if (_wcsicmp(dot, L".bat") == 0 ||
3358 +                   _wcsicmp(dot, L".cmd") == 0 ||
3359 +                   _wcsicmp(dot, L".exe") == 0 ||
3360 +                   _wcsicmp(dot, L".com") == 0)
3361 +                       result->st_mode |= 0111;
3362 +       }
3363 +       return code;
3364 +}
3365 +
3366 +static int
3367 +win32_fstat(int file_number, struct win32_stat *result)
3368 +{
3369 +       BY_HANDLE_FILE_INFORMATION info;
3370 +       HANDLE h;
3371 +       int type;
3372 +    
3373 +       h = (HANDLE)_get_osfhandle(file_number);
3374 +    
3375 +       /* Protocol violation: we explicitly clear errno, instead of
3376 +          setting it to a POSIX error. Callers should use GetLastError. */
3377 +       errno = 0;
3378 +
3379 +       if (h == INVALID_HANDLE_VALUE) {
3380 +               /* This is really a C library error (invalid file handle).
3381 +                  We set the Win32 error to the closes one matching. */
3382 +               SetLastError(ERROR_INVALID_HANDLE);
3383 +               return -1;
3384 +       }
3385 +       memset(result, 0, sizeof(*result));
3386 +
3387 +       type = GetFileType(h);
3388 +       if (type == FILE_TYPE_UNKNOWN) {
3389 +           DWORD error = GetLastError();
3390 +           if (error != 0) {
3391 +               return -1;
3392 +           }
3393 +           /* else: valid but unknown file */
3394 +       }
3395 +
3396 +       if (type != FILE_TYPE_DISK) {
3397 +               if (type == FILE_TYPE_CHAR)
3398 +                       result->st_mode = _S_IFCHR;
3399 +               else if (type == FILE_TYPE_PIPE)
3400 +                       result->st_mode = _S_IFIFO;
3401 +               return 0;
3402 +       }
3403 +
3404 +       if (!GetFileInformationByHandle(h, &info)) {
3405 +               return -1;
3406 +       }
3407 +
3408 +       /* similar to stat() */
3409 +       result->st_mode = attributes_to_mode(info.dwFileAttributes);
3410 +       result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
3411 +       FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
3412 +       FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
3413 +       FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
3414 +       /* specific to fstat() */
3415 +       result->st_nlink = info.nNumberOfLinks;
3416 +       result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
3417 +       return 0;
3418 +}
3419 +
3420 +#endif /* MS_WINDOWS */
3421 +
3422 +PyDoc_STRVAR(stat_result__doc__,
3423 +"stat_result: Result from stat or lstat.\n\n\
3424 +This object may be accessed either as a tuple of\n\
3425 +  (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3426 +or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
3427 +\n\
3428 +Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
3429 +or st_flags, they are available as attributes only.\n\
3430 +\n\
3431 +See os.stat for more information.");
3432 +
3433 +static PyStructSequence_Field stat_result_fields[] = {
3434 +       {"st_mode",    "protection bits"},
3435 +       {"st_ino",     "inode"},
3436 +       {"st_dev",     "device"},
3437 +       {"st_nlink",   "number of hard links"},
3438 +       {"st_uid",     "user ID of owner"},
3439 +       {"st_gid",     "group ID of owner"},
3440 +       {"st_size",    "total size, in bytes"},
3441 +       /* The NULL is replaced with PyStructSequence_UnnamedField later. */
3442 +       {NULL,   "integer time of last access"},
3443 +       {NULL,   "integer time of last modification"},
3444 +       {NULL,   "integer time of last change"},
3445 +       {"st_atime",   "time of last access"},
3446 +       {"st_mtime",   "time of last modification"},
3447 +       {"st_ctime",   "time of last change"},
3448 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
3449 +       {"st_blksize", "blocksize for filesystem I/O"},
3450 +#endif
3451 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3452 +       {"st_blocks",  "number of blocks allocated"},
3453 +#endif
3454 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3455 +       {"st_rdev",    "device type (if inode device)"},
3456 +#endif
3457 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3458 +       {"st_flags",   "user defined flags for file"},
3459 +#endif
3460 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3461 +       {"st_gen",    "generation number"},
3462 +#endif
3463 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3464 +       {"st_birthtime",   "time of creation"},
3465 +#endif
3466 +       {0}
3467 +};
3468 +
3469 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
3470 +#define ST_BLKSIZE_IDX 13
3471 +#else
3472 +#define ST_BLKSIZE_IDX 12
3473 +#endif
3474 +
3475 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3476 +#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
3477 +#else
3478 +#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
3479 +#endif
3480 +
3481 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3482 +#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
3483 +#else
3484 +#define ST_RDEV_IDX ST_BLOCKS_IDX
3485 +#endif
3486 +
3487 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3488 +#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
3489 +#else
3490 +#define ST_FLAGS_IDX ST_RDEV_IDX
3491 +#endif
3492 +
3493 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3494 +#define ST_GEN_IDX (ST_FLAGS_IDX+1)
3495 +#else
3496 +#define ST_GEN_IDX ST_FLAGS_IDX
3497 +#endif
3498 +
3499 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3500 +#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
3501 +#else
3502 +#define ST_BIRTHTIME_IDX ST_GEN_IDX
3503 +#endif
3504 +
3505 +static PyStructSequence_Desc stat_result_desc = {
3506 +       "stat_result", /* name */
3507 +       stat_result__doc__, /* doc */
3508 +       stat_result_fields,
3509 +       10
3510 +};
3511 +
3512 +PyDoc_STRVAR(statvfs_result__doc__,
3513 +"statvfs_result: Result from statvfs or fstatvfs.\n\n\
3514 +This object may be accessed either as a tuple of\n\
3515 +  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
3516 +or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
3517 +\n\
3518 +See os.statvfs for more information.");
3519 +
3520 +static PyStructSequence_Field statvfs_result_fields[] = {
3521 +        {"f_bsize",  },
3522 +        {"f_frsize", },
3523 +        {"f_blocks", },
3524 +        {"f_bfree",  },
3525 +        {"f_bavail", },
3526 +        {"f_files",  },
3527 +        {"f_ffree",  },
3528 +        {"f_favail", },
3529 +        {"f_flag",   },
3530 +        {"f_namemax",},
3531 +        {0}
3532 +};
3533 +
3534 +static PyStructSequence_Desc statvfs_result_desc = {
3535 +       "statvfs_result", /* name */
3536 +       statvfs_result__doc__, /* doc */
3537 +       statvfs_result_fields,
3538 +       10
3539 +};
3540 +
3541 +static int initialized;
3542 +static PyTypeObject StatResultType;
3543 +static PyTypeObject StatVFSResultType;
3544 +static newfunc structseq_new;
3545 +
3546 +static PyObject *
3547 +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3548 +{
3549 +       PyStructSequence *result;
3550 +       int i;
3551 +
3552 +       result = (PyStructSequence*)structseq_new(type, args, kwds);
3553 +       if (!result)
3554 +               return NULL;
3555 +       /* If we have been initialized from a tuple,
3556 +          st_?time might be set to None. Initialize it
3557 +          from the int slots.  */
3558 +       for (i = 7; i <= 9; i++) {
3559 +               if (result->ob_item[i+3] == Py_None) {
3560 +                       Py_DECREF(Py_None);
3561 +                       Py_INCREF(result->ob_item[i]);
3562 +                       result->ob_item[i+3] = result->ob_item[i];
3563 +               }
3564 +       }
3565 +       return (PyObject*)result;
3566 +}
3567 +
3568 +
3569 +
3570 +/* If true, st_?time is float. */
3571 +static int _stat_float_times = 1;
3572 +
3573 +PyDoc_STRVAR(stat_float_times__doc__,
3574 +"stat_float_times([newval]) -> oldval\n\n\
3575 +Determine whether os.[lf]stat represents time stamps as float objects.\n\
3576 +If newval is True, future calls to stat() return floats, if it is False,\n\
3577 +future calls return ints. \n\
3578 +If newval is omitted, return the current setting.\n");
3579 +
3580 +static PyObject*
3581 +stat_float_times(PyObject* self, PyObject *args)
3582 +{
3583 +       int newval = -1;
3584 +       if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
3585 +               return NULL;
3586 +       if (newval == -1)
3587 +               /* Return old value */
3588 +               return PyBool_FromLong(_stat_float_times);
3589 +       _stat_float_times = newval;
3590 +       Py_INCREF(Py_None);
3591 +       return Py_None;
3592 +}
3593 +
3594 +static void
3595 +fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
3596 +{
3597 +       PyObject *fval,*ival;
3598 +#if SIZEOF_TIME_T > SIZEOF_LONG
3599 +       ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
3600 +#else
3601 +       ival = PyInt_FromLong((long)sec);
3602 +#endif
3603 +       if (!ival)
3604 +               return;
3605 +       if (_stat_float_times) {
3606 +               fval = PyFloat_FromDouble(sec + 1e-9*nsec);
3607 +       } else {
3608 +               fval = ival;
3609 +               Py_INCREF(fval);
3610 +       }
3611 +       PyStructSequence_SET_ITEM(v, index, ival);
3612 +       PyStructSequence_SET_ITEM(v, index+3, fval);
3613 +}
3614 +
3615 +/* pack a system stat C structure into the Python stat tuple
3616 +   (used by posix_stat() and posix_fstat()) */
3617 +static PyObject*
3618 +_pystat_fromstructstat(STRUCT_STAT *st)
3619 +{
3620 +       unsigned long ansec, mnsec, cnsec;
3621 +       PyObject *v = PyStructSequence_New(&StatResultType);
3622 +       if (v == NULL)
3623 +               return NULL;
3624 +
3625 +        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
3626 +#ifdef HAVE_LARGEFILE_SUPPORT
3627 +        PyStructSequence_SET_ITEM(v, 1,
3628 +                                 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
3629 +#else
3630 +        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
3631 +#endif
3632 +#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
3633 +        PyStructSequence_SET_ITEM(v, 2,
3634 +                                 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
3635 +#else
3636 +        PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
3637 +#endif
3638 +        PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
3639 +        PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
3640 +        PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
3641 +#ifdef HAVE_LARGEFILE_SUPPORT
3642 +        PyStructSequence_SET_ITEM(v, 6,
3643 +                                 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
3644 +#else
3645 +        PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
3646 +#endif
3647 +
3648 +#if defined(HAVE_STAT_TV_NSEC)
3649 +       ansec = st->st_atim.tv_nsec;
3650 +       mnsec = st->st_mtim.tv_nsec;
3651 +       cnsec = st->st_ctim.tv_nsec;
3652 +#elif defined(HAVE_STAT_TV_NSEC2)
3653 +       ansec = st->st_atimespec.tv_nsec;
3654 +       mnsec = st->st_mtimespec.tv_nsec;
3655 +       cnsec = st->st_ctimespec.tv_nsec;
3656 +#elif defined(HAVE_STAT_NSEC)
3657 +       ansec = st->st_atime_nsec;
3658 +       mnsec = st->st_mtime_nsec;
3659 +       cnsec = st->st_ctime_nsec;
3660 +#else
3661 +       ansec = mnsec = cnsec = 0;
3662 +#endif
3663 +       fill_time(v, 7, st->st_atime, ansec);
3664 +       fill_time(v, 8, st->st_mtime, mnsec);
3665 +       fill_time(v, 9, st->st_ctime, cnsec);
3666 +
3667 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
3668 +       PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
3669 +                        PyInt_FromLong((long)st->st_blksize));
3670 +#endif
3671 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3672 +       PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
3673 +                        PyInt_FromLong((long)st->st_blocks));
3674 +#endif
3675 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3676 +       PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
3677 +                        PyInt_FromLong((long)st->st_rdev));
3678 +#endif
3679 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3680 +       PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
3681 +                        PyInt_FromLong((long)st->st_gen));
3682 +#endif
3683 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3684 +       {
3685 +         PyObject *val;
3686 +         unsigned long bsec,bnsec;
3687 +         bsec = (long)st->st_birthtime;
3688 +#ifdef HAVE_STAT_TV_NSEC2
3689 +         bnsec = st->st_birthtimespec.tv_nsec;
3690 +#else
3691 +         bnsec = 0;
3692 +#endif
3693 +         if (_stat_float_times) {
3694 +           val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
3695 +         } else {
3696 +           val = PyInt_FromLong((long)bsec);
3697 +         }
3698 +         PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
3699 +                                   val);
3700 +       }
3701 +#endif
3702 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3703 +       PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
3704 +                        PyInt_FromLong((long)st->st_flags));
3705 +#endif
3706 +
3707 +       if (PyErr_Occurred()) {
3708 +               Py_DECREF(v);
3709 +               return NULL;
3710 +       }
3711 +
3712 +       return v;
3713 +}
3714 +
3715 +#ifdef MS_WINDOWS
3716 +
3717 +/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
3718 +   where / can be used in place of \ and the trailing slash is optional.
3719 +   Both SERVER and SHARE must have at least one character.
3720 +*/
3721 +
3722 +#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
3723 +#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
3724 +#ifndef ARRAYSIZE
3725 +#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
3726 +#endif
3727 +
3728 +static BOOL
3729 +IsUNCRootA(char *path, int pathlen)
3730 +{
3731 +       #define ISSLASH ISSLASHA
3732 +
3733 +       int i, share;
3734 +
3735 +       if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
3736 +               /* minimum UNCRoot is \\x\y */
3737 +               return FALSE;
3738 +       for (i = 2; i < pathlen ; i++)
3739 +               if (ISSLASH(path[i])) break;
3740 +       if (i == 2 || i == pathlen)
3741 +               /* do not allow \\\SHARE or \\SERVER */
3742 +               return FALSE;
3743 +       share = i+1;
3744 +       for (i = share; i < pathlen; i++)
3745 +               if (ISSLASH(path[i])) break;
3746 +       return (i != share && (i == pathlen || i == pathlen-1));
3747 +
3748 +       #undef ISSLASH
3749 +}
3750 +
3751 +#ifdef Py_WIN_WIDE_FILENAMES
3752 +static BOOL
3753 +IsUNCRootW(Py_UNICODE *path, int pathlen)
3754 +{
3755 +       #define ISSLASH ISSLASHW
3756 +
3757 +       int i, share;
3758 +
3759 +       if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
3760 +               /* minimum UNCRoot is \\x\y */
3761 +               return FALSE;
3762 +       for (i = 2; i < pathlen ; i++)
3763 +               if (ISSLASH(path[i])) break;
3764 +       if (i == 2 || i == pathlen)
3765 +               /* do not allow \\\SHARE or \\SERVER */
3766 +               return FALSE;
3767 +       share = i+1;
3768 +       for (i = share; i < pathlen; i++)
3769 +               if (ISSLASH(path[i])) break;
3770 +       return (i != share && (i == pathlen || i == pathlen-1));
3771 +
3772 +       #undef ISSLASH
3773 +}
3774 +#endif /* Py_WIN_WIDE_FILENAMES */
3775 +#endif /* MS_WINDOWS */
3776 +
3777 +static PyObject *
3778 +posix_do_stat(PyObject *self, PyObject *args,
3779 +             char *format,
3780 +#ifdef __VMS
3781 +             int (*statfunc)(const char *, STRUCT_STAT *, ...),
3782 +#else
3783 +             int (*statfunc)(const char *, STRUCT_STAT *),
3784 +#endif
3785 +             char *wformat,
3786 +             int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
3787 +{
3788 +       STRUCT_STAT st;
3789 +       char *path = NULL;      /* pass this to stat; do not free() it */
3790 +       char *pathfree = NULL;  /* this memory must be free'd */
3791 +       int res;
3792 +       PyObject *result;
3793 +
3794 +#ifdef Py_WIN_WIDE_FILENAMES
3795 +       /* If on wide-character-capable OS see if argument
3796 +          is Unicode and if so use wide API.  */
3797 +       if (unicode_file_names()) {
3798 +               PyUnicodeObject *po;
3799 +               if (PyArg_ParseTuple(args, wformat, &po)) {
3800 +                       Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
3801 +
3802 +                       Py_BEGIN_ALLOW_THREADS
3803 +                               /* PyUnicode_AS_UNICODE result OK without
3804 +                                  thread lock as it is a simple dereference. */
3805 +                       res = wstatfunc(wpath, &st);
3806 +                       Py_END_ALLOW_THREADS
3807 +
3808 +                       if (res != 0)
3809 +                               return win32_error_unicode("stat", wpath);
3810 +                       return _pystat_fromstructstat(&st);
3811 +               }
3812 +               /* Drop the argument parsing error as narrow strings
3813 +                  are also valid. */
3814 +               PyErr_Clear();
3815 +       }
3816 +#endif
3817 +
3818 +       if (!PyArg_ParseTuple(args, format,
3819 +                             Py_FileSystemDefaultEncoding, &path))
3820 +               return NULL;
3821 +       pathfree = path;
3822 +
3823 +       Py_BEGIN_ALLOW_THREADS
3824 +       res = (*statfunc)(path, &st);
3825 +       Py_END_ALLOW_THREADS
3826 +
3827 +       if (res != 0) {
3828 +#ifdef MS_WINDOWS
3829 +               result = win32_error("stat", pathfree);
3830 +#else
3831 +               result = posix_error_with_filename(pathfree);
3832 +#endif
3833 +       } 
3834 +       else
3835 +               result = _pystat_fromstructstat(&st);
3836 +
3837 +       PyMem_Free(pathfree);
3838 +       return result;
3839 +}
3840 +
3841 +/* POSIX methods */
3842 +
3843 +PyDoc_STRVAR(posix_access__doc__,
3844 +"access(path, mode) -> True if granted, False otherwise\n\n\
3845 +Use the real uid/gid to test for access to a path.  Note that most\n\
3846 +operations will use the effective uid/gid, therefore this routine can\n\
3847 +be used in a suid/sgid environment to test if the invoking user has the\n\
3848 +specified access to the path.  The mode argument can be F_OK to test\n\
3849 +existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
3850 +
3851 +static PyObject *
3852 +posix_access(PyObject *self, PyObject *args)
3853 +{
3854 +       char *path;
3855 +       int mode;
3856 +       
3857 +#ifdef Py_WIN_WIDE_FILENAMES
3858 +       DWORD attr;
3859 +       if (unicode_file_names()) {
3860 +               PyUnicodeObject *po;
3861 +               if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
3862 +                       Py_BEGIN_ALLOW_THREADS
3863 +                       /* PyUnicode_AS_UNICODE OK without thread lock as
3864 +                          it is a simple dereference. */
3865 +                       attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
3866 +                       Py_END_ALLOW_THREADS
3867 +                       goto finish;
3868 +               }
3869 +               /* Drop the argument parsing error as narrow strings
3870 +                  are also valid. */
3871 +               PyErr_Clear();
3872 +       }
3873 +       if (!PyArg_ParseTuple(args, "eti:access",
3874 +                             Py_FileSystemDefaultEncoding, &path, &mode))
3875 +               return 0;
3876 +       Py_BEGIN_ALLOW_THREADS
3877 +       attr = GetFileAttributesA(path);
3878 +       Py_END_ALLOW_THREADS
3879 +       PyMem_Free(path);
3880 +finish:
3881 +       if (attr == 0xFFFFFFFF)
3882 +               /* File does not exist, or cannot read attributes */
3883 +               return PyBool_FromLong(0);
3884 +       /* Access is possible if either write access wasn't requested, or
3885 +          the file isn't read-only, or if it's a directory, as there are
3886 +          no read-only directories on Windows. */
3887 +       return PyBool_FromLong(!(mode & 2) 
3888 +                              || !(attr & FILE_ATTRIBUTE_READONLY)
3889 +                              || (attr & FILE_ATTRIBUTE_DIRECTORY));
3890 +#else
3891 +       int res;
3892 +       if (!PyArg_ParseTuple(args, "eti:access", 
3893 +                             Py_FileSystemDefaultEncoding, &path, &mode))
3894 +               return NULL;
3895 +       Py_BEGIN_ALLOW_THREADS
3896 +       res = access(path, mode);
3897 +       Py_END_ALLOW_THREADS
3898 +       PyMem_Free(path);
3899 +       return PyBool_FromLong(res == 0);
3900 +#endif
3901 +}
3902 +
3903 +#ifndef F_OK
3904 +#define F_OK 0
3905 +#endif
3906 +#ifndef R_OK
3907 +#define R_OK 4
3908 +#endif
3909 +#ifndef W_OK
3910 +#define W_OK 2
3911 +#endif
3912 +#ifndef X_OK
3913 +#define X_OK 1
3914 +#endif
3915 +
3916 +#ifdef HAVE_TTYNAME
3917 +PyDoc_STRVAR(posix_ttyname__doc__,
3918 +"ttyname(fd) -> string\n\n\
3919 +Return the name of the terminal device connected to 'fd'.");
3920 +
3921 +static PyObject *
3922 +posix_ttyname(PyObject *self, PyObject *args)
3923 +{
3924 +       int id;
3925 +       char *ret;
3926 +
3927 +       if (!PyArg_ParseTuple(args, "i:ttyname", &id))
3928 +               return NULL;
3929 +
3930 +#if defined(__VMS)
3931 +        /* file descriptor 0 only, the default input device (stdin) */
3932 +       if (id == 0) {
3933 +               ret = ttyname();
3934 +       }
3935 +       else {
3936 +               ret = NULL;
3937 +       }
3938 +#else
3939 +       ret = ttyname(id);
3940 +#endif
3941 +       if (ret == NULL)
3942 +               return posix_error();
3943 +       return PyString_FromString(ret);
3944 +}
3945 +#endif
3946 +
3947 +#ifdef HAVE_CTERMID
3948 +PyDoc_STRVAR(posix_ctermid__doc__,
3949 +"ctermid() -> string\n\n\
3950 +Return the name of the controlling terminal for this process.");
3951 +
3952 +static PyObject *
3953 +posix_ctermid(PyObject *self, PyObject *noargs)
3954 +{
3955 +        char *ret;
3956 +        char buffer[L_ctermid];
3957 +
3958 +#ifdef USE_CTERMID_R
3959 +       ret = ctermid_r(buffer);
3960 +#else
3961 +        ret = ctermid(buffer);
3962 +#endif
3963 +       if (ret == NULL)
3964 +               return posix_error();
3965 +       return PyString_FromString(buffer);
3966 +}
3967 +#endif
3968 +
3969 +PyDoc_STRVAR(posix_chdir__doc__,
3970 +"chdir(path)\n\n\
3971 +Change the current working directory to the specified path.");
3972 +
3973 +static PyObject *
3974 +posix_chdir(PyObject *self, PyObject *args)
3975 +{
3976 +#ifdef MS_WINDOWS
3977 +       return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
3978 +#elif defined(PYOS_OS2) && defined(PYCC_GCC)
3979 +       return posix_1str(args, "et:chdir", _chdir2);
3980 +#elif defined(__VMS)
3981 +       return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
3982 +#else
3983 +       return posix_1str(args, "et:chdir", chdir);
3984 +#endif
3985 +}
3986 +
3987 +#ifdef HAVE_FCHDIR
3988 +PyDoc_STRVAR(posix_fchdir__doc__,
3989 +"fchdir(fildes)\n\n\
3990 +Change to the directory of the given file descriptor.  fildes must be\n\
3991 +opened on a directory, not a file.");
3992 +
3993 +static PyObject *
3994 +posix_fchdir(PyObject *self, PyObject *fdobj)
3995 +{
3996 +       return posix_fildes(fdobj, fchdir);
3997 +}
3998 +#endif /* HAVE_FCHDIR */
3999 +
4000 +
4001 +PyDoc_STRVAR(posix_chmod__doc__,
4002 +"chmod(path, mode)\n\n\
4003 +Change the access permissions of a file.");
4004 +
4005 +static PyObject *
4006 +posix_chmod(PyObject *self, PyObject *args)
4007 +{
4008 +       char *path = NULL;
4009 +       int i;
4010 +       int res;
4011 +#ifdef Py_WIN_WIDE_FILENAMES
4012 +       DWORD attr;
4013 +       if (unicode_file_names()) {
4014 +               PyUnicodeObject *po;
4015 +               if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
4016 +                       Py_BEGIN_ALLOW_THREADS
4017 +                       attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
4018 +                       if (attr != 0xFFFFFFFF) {
4019 +                               if (i & _S_IWRITE)
4020 +                                       attr &= ~FILE_ATTRIBUTE_READONLY;
4021 +                               else
4022 +                                       attr |= FILE_ATTRIBUTE_READONLY;
4023 +                               res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
4024 +                       }
4025 +                       else
4026 +                               res = 0;
4027 +                       Py_END_ALLOW_THREADS
4028 +                       if (!res)
4029 +                               return win32_error_unicode("chmod",
4030 +                                               PyUnicode_AS_UNICODE(po));
4031 +                       Py_INCREF(Py_None);
4032 +                       return Py_None;
4033 +               }
4034 +               /* Drop the argument parsing error as narrow strings
4035 +                  are also valid. */
4036 +               PyErr_Clear();
4037 +       }
4038 +       if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
4039 +                             &path, &i))
4040 +               return NULL;
4041 +       Py_BEGIN_ALLOW_THREADS
4042 +       attr = GetFileAttributesA(path);
4043 +       if (attr != 0xFFFFFFFF) {
4044 +               if (i & _S_IWRITE)
4045 +                       attr &= ~FILE_ATTRIBUTE_READONLY;
4046 +               else
4047 +                       attr |= FILE_ATTRIBUTE_READONLY;
4048 +               res = SetFileAttributesA(path, attr);
4049 +       }
4050 +       else
4051 +               res = 0;
4052 +       Py_END_ALLOW_THREADS
4053 +       if (!res) {
4054 +               win32_error("chmod", path);
4055 +               PyMem_Free(path);
4056 +               return NULL;
4057 +       }
4058 +       PyMem_Free(path);
4059 +       Py_INCREF(Py_None);
4060 +       return Py_None;
4061 +#else /* Py_WIN_WIDE_FILENAMES */
4062 +       if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
4063 +                             &path, &i))
4064 +               return NULL;
4065 +       Py_BEGIN_ALLOW_THREADS
4066 +       res = chmod(path, i);
4067 +       Py_END_ALLOW_THREADS
4068 +       if (res < 0)
4069 +               return posix_error_with_allocated_filename(path);
4070 +       PyMem_Free(path);
4071 +       Py_INCREF(Py_None);
4072 +       return Py_None;
4073 +#endif
4074 +}
4075 +
4076 +
4077 +#ifdef HAVE_CHROOT
4078 +PyDoc_STRVAR(posix_chroot__doc__,
4079 +"chroot(path)\n\n\
4080 +Change root directory to path.");
4081 +
4082 +static PyObject *
4083 +posix_chroot(PyObject *self, PyObject *args)
4084 +{
4085 +       return posix_1str(args, "et:chroot", chroot);
4086 +}
4087 +#endif
4088 +
4089 +#ifdef HAVE_FSYNC
4090 +PyDoc_STRVAR(posix_fsync__doc__,
4091 +"fsync(fildes)\n\n\
4092 +force write of file with filedescriptor to disk.");
4093 +
4094 +static PyObject *
4095 +posix_fsync(PyObject *self, PyObject *fdobj)
4096 +{
4097 +       return posix_fildes(fdobj, fsync);
4098 +}
4099 +#endif /* HAVE_FSYNC */
4100 +
4101 +#ifdef HAVE_FDATASYNC
4102 +
4103 +#ifdef __hpux
4104 +extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
4105 +#endif
4106 +
4107 +PyDoc_STRVAR(posix_fdatasync__doc__,
4108 +"fdatasync(fildes)\n\n\
4109 +force write of file with filedescriptor to disk.\n\
4110 + does not force update of metadata.");
4111 +
4112 +static PyObject *
4113 +posix_fdatasync(PyObject *self, PyObject *fdobj)
4114 +{
4115 +       return posix_fildes(fdobj, fdatasync);
4116 +}
4117 +#endif /* HAVE_FDATASYNC */
4118 +
4119 +
4120 +#ifdef HAVE_CHOWN
4121 +PyDoc_STRVAR(posix_chown__doc__,
4122 +"chown(path, uid, gid)\n\n\
4123 +Change the owner and group id of path to the numeric uid and gid.");
4124 +
4125 +static PyObject *
4126 +posix_chown(PyObject *self, PyObject *args)
4127 +{
4128 +       char *path = NULL;
4129 +       int uid, gid;
4130 +       int res;
4131 +       if (!PyArg_ParseTuple(args, "etii:chown",
4132 +                             Py_FileSystemDefaultEncoding, &path,
4133 +                             &uid, &gid))
4134 +               return NULL;
4135 +       Py_BEGIN_ALLOW_THREADS
4136 +       res = chown(path, (uid_t) uid, (gid_t) gid);
4137 +       Py_END_ALLOW_THREADS
4138 +       if (res < 0)
4139 +               return posix_error_with_allocated_filename(path);
4140 +       PyMem_Free(path);
4141 +       Py_INCREF(Py_None);
4142 +       return Py_None;
4143 +}
4144 +#endif /* HAVE_CHOWN */
4145 +
4146 +#ifdef HAVE_LCHOWN
4147 +PyDoc_STRVAR(posix_lchown__doc__,
4148 +"lchown(path, uid, gid)\n\n\
4149 +Change the owner and group id of path to the numeric uid and gid.\n\
4150 +This function will not follow symbolic links.");
4151 +
4152 +static PyObject *
4153 +posix_lchown(PyObject *self, PyObject *args)
4154 +{
4155 +       char *path = NULL;
4156 +       int uid, gid;
4157 +       int res;
4158 +       if (!PyArg_ParseTuple(args, "etii:lchown",
4159 +                             Py_FileSystemDefaultEncoding, &path,
4160 +                             &uid, &gid))
4161 +               return NULL;
4162 +       Py_BEGIN_ALLOW_THREADS
4163 +       res = lchown(path, (uid_t) uid, (gid_t) gid);
4164 +       Py_END_ALLOW_THREADS
4165 +       if (res < 0)
4166 +               return posix_error_with_allocated_filename(path);
4167 +       PyMem_Free(path);
4168 +       Py_INCREF(Py_None);
4169 +       return Py_None;
4170 +}
4171 +#endif /* HAVE_LCHOWN */
4172 +
4173 +
4174 +#ifdef HAVE_GETCWD
4175 +PyDoc_STRVAR(posix_getcwd__doc__,
4176 +"getcwd() -> path\n\n\
4177 +Return a string representing the current working directory.");
4178 +
4179 +static PyObject *
4180 +posix_getcwd(PyObject *self, PyObject *noargs)
4181 +{
4182 +       char buf[1026];
4183 +       char *res;
4184 +
4185 +       Py_BEGIN_ALLOW_THREADS
4186 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
4187 +       res = _getcwd2(buf, sizeof buf);
4188 +#else
4189 +       res = getcwd(buf, sizeof buf);
4190 +#endif
4191 +       Py_END_ALLOW_THREADS
4192 +       if (res == NULL)
4193 +               return posix_error();
4194 +       return PyString_FromString(buf);
4195 +}
4196 +
4197 +#ifdef Py_USING_UNICODE
4198 +PyDoc_STRVAR(posix_getcwdu__doc__,
4199 +"getcwdu() -> path\n\n\
4200 +Return a unicode string representing the current working directory.");
4201 +
4202 +static PyObject *
4203 +posix_getcwdu(PyObject *self, PyObject *noargs)
4204 +{
4205 +       char buf[1026];
4206 +       char *res;
4207 +
4208 +#ifdef Py_WIN_WIDE_FILENAMES
4209 +       DWORD len;
4210 +       if (unicode_file_names()) {
4211 +               wchar_t wbuf[1026];
4212 +               wchar_t *wbuf2 = wbuf;
4213 +               PyObject *resobj;
4214 +               Py_BEGIN_ALLOW_THREADS
4215 +               len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
4216 +               /* If the buffer is large enough, len does not include the
4217 +                  terminating \0. If the buffer is too small, len includes
4218 +                  the space needed for the terminator. */
4219 +               if (len >= sizeof wbuf/ sizeof wbuf[0]) {
4220 +                       wbuf2 = malloc(len * sizeof(wchar_t));
4221 +                       if (wbuf2)
4222 +                               len = GetCurrentDirectoryW(len, wbuf2);
4223 +               }
4224 +               Py_END_ALLOW_THREADS
4225 +               if (!wbuf2) {
4226 +                       PyErr_NoMemory();
4227 +                       return NULL;
4228 +               }
4229 +               if (!len) {
4230 +                       if (wbuf2 != wbuf) free(wbuf2);
4231 +                       return win32_error("getcwdu", NULL);
4232 +               }
4233 +               resobj = PyUnicode_FromWideChar(wbuf2, len);
4234 +               if (wbuf2 != wbuf) free(wbuf2);
4235 +               return resobj;
4236 +       }
4237 +#endif
4238 +
4239 +       Py_BEGIN_ALLOW_THREADS
4240 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
4241 +       res = _getcwd2(buf, sizeof buf);
4242 +#else
4243 +       res = getcwd(buf, sizeof buf);
4244 +#endif
4245 +       Py_END_ALLOW_THREADS
4246 +       if (res == NULL)
4247 +               return posix_error();
4248 +       return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
4249 +}
4250 +#endif
4251 +#endif
4252 +
4253 +
4254 +#ifdef HAVE_LINK
4255 +PyDoc_STRVAR(posix_link__doc__,
4256 +"link(src, dst)\n\n\
4257 +Create a hard link to a file.");
4258 +
4259 +static PyObject *
4260 +posix_link(PyObject *self, PyObject *args)
4261 +{
4262 +       return posix_2str(args, "etet:link", link);
4263 +}
4264 +#endif /* HAVE_LINK */
4265 +
4266 +
4267 +PyDoc_STRVAR(posix_listdir__doc__,
4268 +"listdir(path) -> list_of_strings\n\n\
4269 +Return a list containing the names of the entries in the directory.\n\
4270 +\n\
4271 +       path: path of directory to list\n\
4272 +\n\
4273 +The list is in arbitrary order.  It does not include the special\n\
4274 +entries '.' and '..' even if they are present in the directory.");
4275 +
4276 +static PyObject *
4277 +posix_listdir(PyObject *self, PyObject *args)
4278 +{
4279 +       /* XXX Should redo this putting the (now four) versions of opendir
4280 +          in separate files instead of having them all here... */
4281 +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4282 +
4283 +       PyObject *d, *v;
4284 +       HANDLE hFindFile;
4285 +       BOOL result;
4286 +       WIN32_FIND_DATA FileData;
4287 +       char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
4288 +       char *bufptr = namebuf;
4289 +       Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
4290 +
4291 +#ifdef Py_WIN_WIDE_FILENAMES
4292 +       /* If on wide-character-capable OS see if argument
4293 +          is Unicode and if so use wide API.  */
4294 +       if (unicode_file_names()) {
4295 +               PyObject *po;
4296 +               if (PyArg_ParseTuple(args, "U:listdir", &po)) {
4297 +                       WIN32_FIND_DATAW wFileData;
4298 +                       Py_UNICODE *wnamebuf;
4299 +                       Py_UNICODE wch;
4300 +                       /* Overallocate for \\*.*\0 */
4301 +                       len = PyUnicode_GET_SIZE(po);
4302 +                       wnamebuf = malloc((len + 5) * sizeof(wchar_t));
4303 +                       if (!wnamebuf) {
4304 +                               PyErr_NoMemory();
4305 +                               return NULL;
4306 +                       }
4307 +                       wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
4308 +                       wch = len > 0 ? wnamebuf[len-1] : '\0';
4309 +                       if (wch != L'/' && wch != L'\\' && wch != L':')
4310 +                               wnamebuf[len++] = L'\\';
4311 +                       wcscpy(wnamebuf + len, L"*.*");
4312 +                       if ((d = PyList_New(0)) == NULL) {
4313 +                               free(wnamebuf);
4314 +                               return NULL;
4315 +                       }
4316 +                       hFindFile = FindFirstFileW(wnamebuf, &wFileData);
4317 +                       if (hFindFile == INVALID_HANDLE_VALUE) {
4318 +                               int error = GetLastError();
4319 +                               if (error == ERROR_FILE_NOT_FOUND) {
4320 +                                       free(wnamebuf);
4321 +                                       return d;
4322 +                               }
4323 +                               Py_DECREF(d);
4324 +                               win32_error_unicode("FindFirstFileW", wnamebuf);
4325 +                               free(wnamebuf);
4326 +                               return NULL;
4327 +                       }
4328 +                       do {
4329 +                               /* Skip over . and .. */
4330 +                               if (wcscmp(wFileData.cFileName, L".") != 0 &&
4331 +                                   wcscmp(wFileData.cFileName, L"..") != 0) {
4332 +                                       v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
4333 +                                       if (v == NULL) {
4334 +                                               Py_DECREF(d);
4335 +                                               d = NULL;
4336 +                                               break;
4337 +                                       }
4338 +                                       if (PyList_Append(d, v) != 0) {
4339 +                                               Py_DECREF(v);
4340 +                                               Py_DECREF(d);
4341 +                                               d = NULL;
4342 +                                               break;
4343 +                                       }
4344 +                                       Py_DECREF(v);
4345 +                               }
4346 +                               Py_BEGIN_ALLOW_THREADS
4347 +                               result = FindNextFileW(hFindFile, &wFileData);
4348 +                               Py_END_ALLOW_THREADS
4349 +                               /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4350 +                                  it got to the end of the directory. */
4351 +                               if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
4352 +                                   Py_DECREF(d);
4353 +                                   win32_error_unicode("FindNextFileW", wnamebuf);
4354 +                                   FindClose(hFindFile);
4355 +                                   free(wnamebuf);
4356 +                                   return NULL;
4357 +                               }
4358 +                       } while (result == TRUE);
4359 +
4360 +                       if (FindClose(hFindFile) == FALSE) {
4361 +                               Py_DECREF(d);
4362 +                               win32_error_unicode("FindClose", wnamebuf);
4363 +                               free(wnamebuf);
4364 +                               return NULL;
4365 +                       }
4366 +                       free(wnamebuf);
4367 +                       return d;
4368 +               }
4369 +               /* Drop the argument parsing error as narrow strings
4370 +                  are also valid. */
4371 +               PyErr_Clear();
4372 +       }
4373 +#endif
4374 +
4375 +       if (!PyArg_ParseTuple(args, "et#:listdir",
4376 +                             Py_FileSystemDefaultEncoding, &bufptr, &len))
4377 +               return NULL;
4378 +       if (len > 0) {
4379 +               char ch = namebuf[len-1];
4380 +               if (ch != SEP && ch != ALTSEP && ch != ':')
4381 +                       namebuf[len++] = '/';
4382 +       }
4383 +       strcpy(namebuf + len, "*.*");
4384 +
4385 +       if ((d = PyList_New(0)) == NULL)
4386 +               return NULL;
4387 +
4388 +       hFindFile = FindFirstFile(namebuf, &FileData);
4389 +       if (hFindFile == INVALID_HANDLE_VALUE) {
4390 +               int error = GetLastError();
4391 +               if (error == ERROR_FILE_NOT_FOUND)
4392 +                       return d;
4393 +               Py_DECREF(d);
4394 +               return win32_error("FindFirstFile", namebuf);
4395 +       }
4396 +       do {
4397 +               /* Skip over . and .. */
4398 +               if (strcmp(FileData.cFileName, ".") != 0 &&
4399 +                   strcmp(FileData.cFileName, "..") != 0) {
4400 +                       v = PyString_FromString(FileData.cFileName);
4401 +                       if (v == NULL) {
4402 +                               Py_DECREF(d);
4403 +                               d = NULL;
4404 +                               break;
4405 +                       }
4406 +                       if (PyList_Append(d, v) != 0) {
4407 +                               Py_DECREF(v);
4408 +                               Py_DECREF(d);
4409 +                               d = NULL;
4410 +                               break;
4411 +                       }
4412 +                       Py_DECREF(v);
4413 +               }
4414 +               Py_BEGIN_ALLOW_THREADS
4415 +               result = FindNextFile(hFindFile, &FileData);
4416 +               Py_END_ALLOW_THREADS
4417 +               /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4418 +                  it got to the end of the directory. */
4419 +               if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
4420 +                   Py_DECREF(d);
4421 +                   win32_error("FindNextFile", namebuf);
4422 +                   FindClose(hFindFile);
4423 +                   return NULL;
4424 +               }
4425 +       } while (result == TRUE);
4426 +
4427 +       if (FindClose(hFindFile) == FALSE) {
4428 +               Py_DECREF(d);
4429 +               return win32_error("FindClose", namebuf);
4430 +       }
4431 +
4432 +       return d;
4433 +
4434 +#elif defined(PYOS_OS2)
4435 +
4436 +#ifndef MAX_PATH
4437 +#define MAX_PATH    CCHMAXPATH
4438 +#endif
4439 +    char *name, *pt;
4440 +    Py_ssize_t len;
4441 +    PyObject *d, *v;
4442 +    char namebuf[MAX_PATH+5];
4443 +    HDIR  hdir = 1;
4444 +    ULONG srchcnt = 1;
4445 +    FILEFINDBUF3   ep;
4446 +    APIRET rc;
4447 +
4448 +    if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
4449 +        return NULL;
4450 +    if (len >= MAX_PATH) {
4451 +               PyErr_SetString(PyExc_ValueError, "path too long");
4452 +        return NULL;
4453 +    }
4454 +    strcpy(namebuf, name);
4455 +    for (pt = namebuf; *pt; pt++)
4456 +        if (*pt == ALTSEP)
4457 +            *pt = SEP;
4458 +    if (namebuf[len-1] != SEP)
4459 +        namebuf[len++] = SEP;
4460 +    strcpy(namebuf + len, "*.*");
4461 +
4462 +       if ((d = PyList_New(0)) == NULL)
4463 +        return NULL;
4464 +
4465 +    rc = DosFindFirst(namebuf,         /* Wildcard Pattern to Match */
4466 +                      &hdir,           /* Handle to Use While Search Directory */
4467 +                      FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
4468 +                      &ep, sizeof(ep), /* Structure to Receive Directory Entry */
4469 +                      &srchcnt,        /* Max and Actual Count of Entries Per Iteration */
4470 +                      FIL_STANDARD);   /* Format of Entry (EAs or Not) */
4471 +
4472 +    if (rc != NO_ERROR) {
4473 +        errno = ENOENT;
4474 +        return posix_error_with_filename(name);
4475 +    }
4476 +
4477 +    if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
4478 +        do {
4479 +            if (ep.achName[0] == '.'
4480 +            && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
4481 +                continue; /* Skip Over "." and ".." Names */
4482 +
4483 +            strcpy(namebuf, ep.achName);
4484 +
4485 +            /* Leave Case of Name Alone -- In Native Form */
4486 +            /* (Removed Forced Lowercasing Code) */
4487 +
4488 +            v = PyString_FromString(namebuf);
4489 +            if (v == NULL) {
4490 +                Py_DECREF(d);
4491 +                d = NULL;
4492 +                break;
4493 +            }
4494 +            if (PyList_Append(d, v) != 0) {
4495 +                Py_DECREF(v);
4496 +                Py_DECREF(d);
4497 +                d = NULL;
4498 +                break;
4499 +            }
4500 +            Py_DECREF(v);
4501 +        } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
4502 +    }
4503 +
4504 +    return d;
4505 +#else
4506 +
4507 +       char *name = NULL;
4508 +       PyObject *d, *v;
4509 +       DIR *dirp;
4510 +       struct dirent *ep;
4511 +       int arg_is_unicode = 1;
4512 +
4513 +       if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
4514 +               arg_is_unicode = 0;
4515 +               PyErr_Clear();
4516 +       }
4517 +       if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
4518 +               return NULL;
4519 +       if ((dirp = opendir(name)) == NULL) {
4520 +               return posix_error_with_allocated_filename(name);
4521 +       }
4522 +       if ((d = PyList_New(0)) == NULL) {
4523 +               closedir(dirp);
4524 +               PyMem_Free(name);
4525 +               return NULL;
4526 +       }
4527 +       for (;;) {
4528 +               errno = 0;
4529 +               Py_BEGIN_ALLOW_THREADS
4530 +               ep = readdir(dirp);
4531 +               Py_END_ALLOW_THREADS
4532 +               if (ep == NULL)
4533 +                       break;
4534 +               if (ep->d_name[0] == '.' &&
4535 +                   (NAMLEN(ep) == 1 ||
4536 +                    (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4537 +                       continue;
4538 +               v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
4539 +               if (v == NULL) {
4540 +                       Py_DECREF(d);
4541 +                       d = NULL;
4542 +                       break;
4543 +               }
4544 +#ifdef Py_USING_UNICODE
4545 +               if (arg_is_unicode) {
4546 +                       PyObject *w;
4547 +
4548 +                       w = PyUnicode_FromEncodedObject(v,
4549 +                                       Py_FileSystemDefaultEncoding,
4550 +                                       "strict");
4551 +                       if (w != NULL) {
4552 +                               Py_DECREF(v);
4553 +                               v = w;
4554 +                       }
4555 +                       else {
4556 +                               /* fall back to the original byte string, as
4557 +                                  discussed in patch #683592 */
4558 +                               PyErr_Clear();
4559 +                       }
4560 +               }
4561 +#endif
4562 +               if (PyList_Append(d, v) != 0) {
4563 +                       Py_DECREF(v);
4564 +                       Py_DECREF(d);
4565 +                       d = NULL;
4566 +                       break;
4567 +               }
4568 +               Py_DECREF(v);
4569 +       }
4570 +       if (errno != 0 && d != NULL) {
4571 +               /* readdir() returned NULL and set errno */
4572 +               closedir(dirp);
4573 +               Py_DECREF(d);
4574 +               return posix_error_with_allocated_filename(name); 
4575 +       }
4576 +       closedir(dirp);
4577 +       PyMem_Free(name);
4578 +
4579 +       return d;
4580 +
4581 +#endif /* which OS */
4582 +}  /* end of posix_listdir */
4583 +
4584 +#ifdef MS_WINDOWS
4585 +/* A helper function for abspath on win32 */
4586 +static PyObject *
4587 +posix__getfullpathname(PyObject *self, PyObject *args)
4588 +{
4589 +       /* assume encoded strings wont more than double no of chars */
4590 +       char inbuf[MAX_PATH*2];
4591 +       char *inbufp = inbuf;
4592 +       Py_ssize_t insize = sizeof(inbuf);
4593 +       char outbuf[MAX_PATH*2];
4594 +       char *temp;
4595 +#ifdef Py_WIN_WIDE_FILENAMES
4596 +       if (unicode_file_names()) {
4597 +               PyUnicodeObject *po;
4598 +               if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
4599 +                       Py_UNICODE woutbuf[MAX_PATH*2];
4600 +                       Py_UNICODE *wtemp;
4601 +                       if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
4602 +                                               sizeof(woutbuf)/sizeof(woutbuf[0]),
4603 +                                                woutbuf, &wtemp))
4604 +                               return win32_error("GetFullPathName", "");
4605 +                       return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
4606 +               }
4607 +               /* Drop the argument parsing error as narrow strings
4608 +                  are also valid. */
4609 +               PyErr_Clear();
4610 +       }
4611 +#endif
4612 +       if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
4613 +                              Py_FileSystemDefaultEncoding, &inbufp,
4614 +                              &insize))
4615 +               return NULL;
4616 +       if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
4617 +                            outbuf, &temp))
4618 +               return win32_error("GetFullPathName", inbuf);
4619 +       if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
4620 +               return PyUnicode_Decode(outbuf, strlen(outbuf),
4621 +                       Py_FileSystemDefaultEncoding, NULL);
4622 +       }
4623 +       return PyString_FromString(outbuf);
4624 +} /* end of posix__getfullpathname */
4625 +#endif /* MS_WINDOWS */
4626 +
4627 +PyDoc_STRVAR(posix_mkdir__doc__,
4628 +"mkdir(path [, mode=0777])\n\n\
4629 +Create a directory.");
4630 +
4631 +static PyObject *
4632 +posix_mkdir(PyObject *self, PyObject *args)
4633 +{
4634 +       int res;
4635 +       char *path = NULL;
4636 +       int mode = 0777;
4637 +
4638 +#ifdef Py_WIN_WIDE_FILENAMES
4639 +       if (unicode_file_names()) {
4640 +               PyUnicodeObject *po;
4641 +               if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
4642 +                       Py_BEGIN_ALLOW_THREADS
4643 +                       /* PyUnicode_AS_UNICODE OK without thread lock as
4644 +                          it is a simple dereference. */
4645 +                       res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
4646 +                       Py_END_ALLOW_THREADS
4647 +                       if (!res)
4648 +                               return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
4649 +                       Py_INCREF(Py_None);
4650 +                       return Py_None;
4651 +               }
4652 +               /* Drop the argument parsing error as narrow strings
4653 +                  are also valid. */
4654 +               PyErr_Clear();
4655 +       }
4656 +       if (!PyArg_ParseTuple(args, "et|i:mkdir",
4657 +                             Py_FileSystemDefaultEncoding, &path, &mode))
4658 +               return NULL;
4659 +       Py_BEGIN_ALLOW_THREADS
4660 +       /* PyUnicode_AS_UNICODE OK without thread lock as
4661 +          it is a simple dereference. */
4662 +       res = CreateDirectoryA(path, NULL);
4663 +       Py_END_ALLOW_THREADS
4664 +       if (!res) {
4665 +               win32_error("mkdir", path);
4666 +               PyMem_Free(path);
4667 +               return NULL;
4668 +       }
4669 +       PyMem_Free(path);
4670 +       Py_INCREF(Py_None);
4671 +       return Py_None;
4672 +#else
4673 +
4674 +       if (!PyArg_ParseTuple(args, "et|i:mkdir",
4675 +                             Py_FileSystemDefaultEncoding, &path, &mode))
4676 +               return NULL;
4677 +       Py_BEGIN_ALLOW_THREADS
4678 +#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
4679 +       res = mkdir(path);
4680 +#else
4681 +       res = mkdir(path, mode);
4682 +#endif
4683 +       Py_END_ALLOW_THREADS
4684 +       if (res < 0)
4685 +               return posix_error_with_allocated_filename(path);
4686 +       PyMem_Free(path);
4687 +       Py_INCREF(Py_None);
4688 +       return Py_None;
4689 +#endif
4690 +}
4691 +
4692 +
4693 +/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4694 +#if defined(HAVE_SYS_RESOURCE_H)
4695 +#include <sys/resource.h>
4696 +#endif
4697 +
4698 +
4699 +#ifdef HAVE_NICE
4700 +PyDoc_STRVAR(posix_nice__doc__,
4701 +"nice(inc) -> new_priority\n\n\
4702 +Decrease the priority of process by inc and return the new priority.");
4703 +
4704 +static PyObject *
4705 +posix_nice(PyObject *self, PyObject *args)
4706 +{
4707 +       int increment, value;
4708 +
4709 +       if (!PyArg_ParseTuple(args, "i:nice", &increment))
4710 +               return NULL;
4711 +
4712 +       /* There are two flavours of 'nice': one that returns the new
4713 +          priority (as required by almost all standards out there) and the
4714 +          Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4715 +          the use of getpriority() to get the new priority.
4716 +
4717 +          If we are of the nice family that returns the new priority, we
4718 +          need to clear errno before the call, and check if errno is filled
4719 +          before calling posix_error() on a returnvalue of -1, because the
4720 +          -1 may be the actual new priority! */
4721 +
4722 +       errno = 0;
4723 +       value = nice(increment);
4724 +#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
4725 +       if (value == 0)
4726 +               value = getpriority(PRIO_PROCESS, 0);
4727 +#endif
4728 +       if (value == -1 && errno != 0)
4729 +               /* either nice() or getpriority() returned an error */
4730 +               return posix_error();
4731 +       return PyInt_FromLong((long) value);
4732 +}
4733 +#endif /* HAVE_NICE */
4734 +
4735 +PyDoc_STRVAR(posix_rename__doc__,
4736 +"rename(old, new)\n\n\
4737 +Rename a file or directory.");
4738 +
4739 +static PyObject *
4740 +posix_rename(PyObject *self, PyObject *args)
4741 +{
4742 +#ifdef MS_WINDOWS
4743 +       PyObject *o1, *o2;
4744 +       char *p1, *p2;
4745 +       BOOL result;
4746 +       if (unicode_file_names()) {
4747 +           if (!PyArg_ParseTuple(args, "O&O&:rename", 
4748 +               convert_to_unicode, &o1,
4749 +               convert_to_unicode, &o2))
4750 +                   PyErr_Clear();
4751 +           else {
4752 +                   Py_BEGIN_ALLOW_THREADS
4753 +                   result = MoveFileW(PyUnicode_AsUnicode(o1),
4754 +                                      PyUnicode_AsUnicode(o2));
4755 +                   Py_END_ALLOW_THREADS
4756 +                   Py_DECREF(o1);
4757 +                   Py_DECREF(o2);
4758 +                   if (!result)
4759 +                           return win32_error("rename", NULL);
4760 +                   Py_INCREF(Py_None);
4761 +                   return Py_None;
4762 +           }
4763 +       }
4764 +       if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
4765 +               return NULL;
4766 +       Py_BEGIN_ALLOW_THREADS
4767 +       result = MoveFileA(p1, p2);
4768 +       Py_END_ALLOW_THREADS
4769 +       if (!result)
4770 +               return win32_error("rename", NULL);
4771 +       Py_INCREF(Py_None);
4772 +       return Py_None;
4773 +#else
4774 +       return posix_2str(args, "etet:rename", rename);
4775 +#endif
4776 +}
4777 +
4778 +
4779 +PyDoc_STRVAR(posix_rmdir__doc__,
4780 +"rmdir(path)\n\n\
4781 +Remove a directory.");
4782 +
4783 +static PyObject *
4784 +posix_rmdir(PyObject *self, PyObject *args)
4785 +{
4786 +#ifdef MS_WINDOWS
4787 +       return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
4788 +#else
4789 +       return posix_1str(args, "et:rmdir", rmdir);
4790 +#endif
4791 +}
4792 +
4793 +
4794 +PyDoc_STRVAR(posix_stat__doc__,
4795 +"stat(path) -> stat result\n\n\
4796 +Perform a stat system call on the given path.");
4797 +
4798 +static PyObject *
4799 +posix_stat(PyObject *self, PyObject *args)
4800 +{
4801 +#ifdef MS_WINDOWS
4802 +       return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
4803 +#else
4804 +       return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
4805 +#endif
4806 +}
4807 +
4808 +
4809 +#ifdef HAVE_SYSTEM
4810 +PyDoc_STRVAR(posix_system__doc__,
4811 +"system(command) -> exit_status\n\n\
4812 +Execute the command (a string) in a subshell.");
4813 +
4814 +static PyObject *
4815 +posix_system(PyObject *self, PyObject *args)
4816 +{
4817 +       char *command;
4818 +       long sts;
4819 +       if (!PyArg_ParseTuple(args, "s:system", &command))
4820 +               return NULL;
4821 +       Py_BEGIN_ALLOW_THREADS
4822 +       sts = system(command);
4823 +       Py_END_ALLOW_THREADS
4824 +       return PyInt_FromLong(sts);
4825 +}
4826 +#endif
4827 +
4828 +
4829 +PyDoc_STRVAR(posix_umask__doc__,
4830 +"umask(new_mask) -> old_mask\n\n\
4831 +Set the current numeric umask and return the previous umask.");
4832 +
4833 +static PyObject *
4834 +posix_umask(PyObject *self, PyObject *args)
4835 +{
4836 +       int i;
4837 +       if (!PyArg_ParseTuple(args, "i:umask", &i))
4838 +               return NULL;
4839 +       i = (int)umask(i);
4840 +       if (i < 0)
4841 +               return posix_error();
4842 +       return PyInt_FromLong((long)i);
4843 +}
4844 +
4845 +
4846 +PyDoc_STRVAR(posix_unlink__doc__,
4847 +"unlink(path)\n\n\
4848 +Remove a file (same as remove(path)).");
4849 +
4850 +PyDoc_STRVAR(posix_remove__doc__,
4851 +"remove(path)\n\n\
4852 +Remove a file (same as unlink(path)).");
4853 +
4854 +static PyObject *
4855 +posix_unlink(PyObject *self, PyObject *args)
4856 +{
4857 +#ifdef MS_WINDOWS
4858 +       return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
4859 +#else
4860 +       return posix_1str(args, "et:remove", unlink);
4861 +#endif
4862 +}
4863 +
4864 +
4865 +#ifdef HAVE_UNAME
4866 +PyDoc_STRVAR(posix_uname__doc__,
4867 +"uname() -> (sysname, nodename, release, version, machine)\n\n\
4868 +Return a tuple identifying the current operating system.");
4869 +
4870 +static PyObject *
4871 +posix_uname(PyObject *self, PyObject *noargs)
4872 +{
4873 +       struct utsname u;
4874 +       int res;
4875 +
4876 +       Py_BEGIN_ALLOW_THREADS
4877 +       res = uname(&u);
4878 +       Py_END_ALLOW_THREADS
4879 +       if (res < 0)
4880 +               return posix_error();
4881 +       return Py_BuildValue("(sssss)",
4882 +                            u.sysname,
4883 +                            u.nodename,
4884 +                            u.release,
4885 +                            u.version,
4886 +                            u.machine);
4887 +}
4888 +#endif /* HAVE_UNAME */
4889 +
4890 +static int
4891 +extract_time(PyObject *t, long* sec, long* usec)
4892 +{
4893 +       long intval;
4894 +       if (PyFloat_Check(t)) {
4895 +               double tval = PyFloat_AsDouble(t);
4896 +               PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
4897 +               if (!intobj)
4898 +                       return -1;
4899 +               intval = PyInt_AsLong(intobj);
4900 +               Py_DECREF(intobj);
4901 +               if (intval == -1 && PyErr_Occurred())
4902 +                       return -1;
4903 +               *sec = intval;
4904 +               *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
4905 +               if (*usec < 0)
4906 +                       /* If rounding gave us a negative number,
4907 +                          truncate.  */
4908 +                       *usec = 0;
4909 +               return 0;
4910 +       }
4911 +       intval = PyInt_AsLong(t);
4912 +       if (intval == -1 && PyErr_Occurred())
4913 +               return -1;
4914 +       *sec = intval;
4915 +       *usec = 0;
4916 +        return 0;
4917 +}
4918 +
4919 +PyDoc_STRVAR(posix_utime__doc__,
4920 +"utime(path, (atime, mtime))\n\
4921 +utime(path, None)\n\n\
4922 +Set the access and modified time of the file to the given values.  If the\n\
4923 +second form is used, set the access and modified times to the current time.");
4924 +
4925 +static PyObject *
4926 +posix_utime(PyObject *self, PyObject *args)
4927 +{
4928 +#ifdef Py_WIN_WIDE_FILENAMES
4929 +       PyObject *arg;
4930 +       PyUnicodeObject *obwpath;
4931 +       wchar_t *wpath = NULL;
4932 +       char *apath = NULL;
4933 +       HANDLE hFile;
4934 +       long atimesec, mtimesec, ausec, musec;
4935 +       FILETIME atime, mtime;
4936 +       PyObject *result = NULL;
4937 +
4938 +       if (unicode_file_names()) {
4939 +               if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
4940 +                       wpath = PyUnicode_AS_UNICODE(obwpath);
4941 +                       Py_BEGIN_ALLOW_THREADS
4942 +                       hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
4943 +                                           NULL, OPEN_EXISTING, 0, NULL);
4944 +                       Py_END_ALLOW_THREADS
4945 +                       if (hFile == INVALID_HANDLE_VALUE)
4946 +                               return win32_error_unicode("utime", wpath);
4947 +               } else
4948 +                       /* Drop the argument parsing error as narrow strings
4949 +                          are also valid. */
4950 +                       PyErr_Clear();
4951 +       }
4952 +       if (!wpath) {
4953 +               if (!PyArg_ParseTuple(args, "etO:utime",
4954 +                               Py_FileSystemDefaultEncoding, &apath, &arg))
4955 +                       return NULL;
4956 +               Py_BEGIN_ALLOW_THREADS
4957 +               hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
4958 +                                   NULL, OPEN_EXISTING, 0, NULL);
4959 +               Py_END_ALLOW_THREADS
4960 +               if (hFile == INVALID_HANDLE_VALUE) {
4961 +                       win32_error("utime", apath);
4962 +                       PyMem_Free(apath);
4963 +                       return NULL;
4964 +               }
4965 +               PyMem_Free(apath);
4966 +       }
4967 +       
4968 +       if (arg == Py_None) {
4969 +               SYSTEMTIME now;
4970 +               GetSystemTime(&now);
4971 +               if (!SystemTimeToFileTime(&now, &mtime) ||
4972 +                   !SystemTimeToFileTime(&now, &atime)) {
4973 +                       win32_error("utime", NULL);
4974 +                       goto done;
4975 +                   }
4976 +       }
4977 +       else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
4978 +               PyErr_SetString(PyExc_TypeError,
4979 +                               "utime() arg 2 must be a tuple (atime, mtime)");
4980 +               goto done;
4981 +       }
4982 +       else {
4983 +               if (extract_time(PyTuple_GET_ITEM(arg, 0),
4984 +                                &atimesec, &ausec) == -1)
4985 +                       goto done;
4986 +               time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
4987 +               if (extract_time(PyTuple_GET_ITEM(arg, 1),
4988 +                                &mtimesec, &musec) == -1)
4989 +                       goto done;
4990 +               time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
4991 +       }
4992 +       if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4993 +               /* Avoid putting the file name into the error here,
4994 +                  as that may confuse the user into believing that
4995 +                  something is wrong with the file, when it also
4996 +                  could be the time stamp that gives a problem. */
4997 +               win32_error("utime", NULL);
4998 +       }
4999 +       Py_INCREF(Py_None);
5000 +       result = Py_None;
5001 +done:
5002 +       CloseHandle(hFile);
5003 +       return result;
5004 +#else /* Py_WIN_WIDE_FILENAMES */
5005 +
5006 +       char *path = NULL;
5007 +       long atime, mtime, ausec, musec;
5008 +       int res;
5009 +       PyObject* arg;
5010 +
5011 +#if defined(HAVE_UTIMES)
5012 +       struct timeval buf[2];
5013 +#define ATIME buf[0].tv_sec
5014 +#define MTIME buf[1].tv_sec
5015 +#elif defined(HAVE_UTIME_H)
5016 +/* XXX should define struct utimbuf instead, above */
5017 +       struct utimbuf buf;
5018 +#define ATIME buf.actime
5019 +#define MTIME buf.modtime
5020 +#define UTIME_ARG &buf
5021 +#else /* HAVE_UTIMES */
5022 +       time_t buf[2];
5023 +#define ATIME buf[0]
5024 +#define MTIME buf[1]
5025 +#define UTIME_ARG buf
5026 +#endif /* HAVE_UTIMES */
5027 +
5028 +
5029 +       if (!PyArg_ParseTuple(args, "etO:utime",
5030 +                                 Py_FileSystemDefaultEncoding, &path, &arg))
5031 +               return NULL;
5032 +       if (arg == Py_None) {
5033 +               /* optional time values not given */
5034 +               Py_BEGIN_ALLOW_THREADS
5035 +               res = utime(path, NULL);
5036 +               Py_END_ALLOW_THREADS
5037 +       }
5038 +       else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
5039 +               PyErr_SetString(PyExc_TypeError,
5040 +                               "utime() arg 2 must be a tuple (atime, mtime)");
5041 +               PyMem_Free(path);
5042 +               return NULL;
5043 +       }
5044 +       else {
5045 +               if (extract_time(PyTuple_GET_ITEM(arg, 0),
5046 +                                &atime, &ausec) == -1) {
5047 +                       PyMem_Free(path);
5048 +                       return NULL;
5049 +               }
5050 +               if (extract_time(PyTuple_GET_ITEM(arg, 1),
5051 +                                &mtime, &musec) == -1) {
5052 +                       PyMem_Free(path);
5053 +                       return NULL;
5054 +               }
5055 +               ATIME = atime;
5056 +               MTIME = mtime;
5057 +#ifdef HAVE_UTIMES
5058 +               buf[0].tv_usec = ausec;
5059 +               buf[1].tv_usec = musec;
5060 +               Py_BEGIN_ALLOW_THREADS
5061 +               res = utimes(path, buf);
5062 +               Py_END_ALLOW_THREADS
5063 +#else
5064 +               Py_BEGIN_ALLOW_THREADS
5065 +               res = utime(path, UTIME_ARG);
5066 +               Py_END_ALLOW_THREADS
5067 +#endif /* HAVE_UTIMES */
5068 +       }
5069 +       if (res < 0) {
5070 +               return posix_error_with_allocated_filename(path);
5071 +       }
5072 +       PyMem_Free(path);
5073 +       Py_INCREF(Py_None);
5074 +       return Py_None;
5075 +#undef UTIME_ARG
5076 +#undef ATIME
5077 +#undef MTIME
5078 +#endif /* Py_WIN_WIDE_FILENAMES */
5079 +}
5080 +
5081 +
5082 +/* Process operations */
5083 +
5084 +PyDoc_STRVAR(posix__exit__doc__,
5085 +"_exit(status)\n\n\
5086 +Exit to the system with specified status, without normal exit processing.");
5087 +
5088 +static PyObject *
5089 +posix__exit(PyObject *self, PyObject *args)
5090 +{
5091 +       int sts;
5092 +       if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5093 +               return NULL;
5094 +       _exit(sts);
5095 +       return NULL; /* Make gcc -Wall happy */
5096 +}
5097 +
5098 +#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5099 +static void
5100 +free_string_array(char **array, Py_ssize_t count)
5101 +{
5102 +       Py_ssize_t i;
5103 +       for (i = 0; i < count; i++)
5104 +               PyMem_Free(array[i]);
5105 +       PyMem_DEL(array);
5106 +}
5107 +#endif
5108 +
5109 +
5110 +#ifdef HAVE_EXECV
5111 +PyDoc_STRVAR(posix_execv__doc__,
5112 +"execv(path, args)\n\n\
5113 +Execute an executable path with arguments, replacing current process.\n\
5114 +\n\
5115 +       path: path of executable file\n\
5116 +       args: tuple or list of strings");
5117 +
5118 +static PyObject *
5119 +posix_execv(PyObject *self, PyObject *args)
5120 +{
5121 +       char *path;
5122 +       PyObject *argv;
5123 +       char **argvlist;
5124 +       Py_ssize_t i, argc;
5125 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5126 +
5127 +       /* execv has two arguments: (path, argv), where
5128 +          argv is a list or tuple of strings. */
5129 +
5130 +       if (!PyArg_ParseTuple(args, "etO:execv",
5131 +                              Py_FileSystemDefaultEncoding,
5132 +                              &path, &argv))
5133 +               return NULL;
5134 +       if (PyList_Check(argv)) {
5135 +               argc = PyList_Size(argv);
5136 +               getitem = PyList_GetItem;
5137 +       }
5138 +       else if (PyTuple_Check(argv)) {
5139 +               argc = PyTuple_Size(argv);
5140 +               getitem = PyTuple_GetItem;
5141 +       }
5142 +       else {
5143 +               PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
5144 +                PyMem_Free(path);
5145 +               return NULL;
5146 +       }
5147 +
5148 +       argvlist = PyMem_NEW(char *, argc+1);
5149 +       if (argvlist == NULL) {
5150 +               PyMem_Free(path);
5151 +               return PyErr_NoMemory();
5152 +       }
5153 +       for (i = 0; i < argc; i++) {
5154 +               if (!PyArg_Parse((*getitem)(argv, i), "et",
5155 +                                Py_FileSystemDefaultEncoding,
5156 +                                &argvlist[i])) {
5157 +                       free_string_array(argvlist, i);
5158 +                       PyErr_SetString(PyExc_TypeError,
5159 +                                       "execv() arg 2 must contain only strings");
5160 +                       PyMem_Free(path);
5161 +                       return NULL;
5162 +
5163 +               }
5164 +       }
5165 +       argvlist[argc] = NULL;
5166 +
5167 +       execv(path, argvlist);
5168 +
5169 +       /* If we get here it's definitely an error */
5170 +
5171 +       free_string_array(argvlist, argc);
5172 +       PyMem_Free(path);
5173 +       return posix_error();
5174 +}
5175 +
5176 +
5177 +PyDoc_STRVAR(posix_execve__doc__,
5178 +"execve(path, args, env)\n\n\
5179 +Execute a path with arguments and environment, replacing current process.\n\
5180 +\n\
5181 +       path: path of executable file\n\
5182 +       args: tuple or list of arguments\n\
5183 +       env: dictionary of strings mapping to strings");
5184 +
5185 +static PyObject *
5186 +posix_execve(PyObject *self, PyObject *args)
5187 +{
5188 +       char *path;
5189 +       PyObject *argv, *env;
5190 +       char **argvlist;
5191 +       char **envlist;
5192 +       PyObject *key, *val, *keys=NULL, *vals=NULL;
5193 +       Py_ssize_t i, pos, argc, envc;
5194 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5195 +       Py_ssize_t lastarg = 0;
5196 +
5197 +       /* execve has three arguments: (path, argv, env), where
5198 +          argv is a list or tuple of strings and env is a dictionary
5199 +          like posix.environ. */
5200 +
5201 +       if (!PyArg_ParseTuple(args, "etOO:execve",
5202 +                             Py_FileSystemDefaultEncoding,
5203 +                             &path, &argv, &env))
5204 +               return NULL;
5205 +       if (PyList_Check(argv)) {
5206 +               argc = PyList_Size(argv);
5207 +               getitem = PyList_GetItem;
5208 +       }
5209 +       else if (PyTuple_Check(argv)) {
5210 +               argc = PyTuple_Size(argv);
5211 +               getitem = PyTuple_GetItem;
5212 +       }
5213 +       else {
5214 +               PyErr_SetString(PyExc_TypeError,
5215 +                               "execve() arg 2 must be a tuple or list");
5216 +               goto fail_0;
5217 +       }
5218 +       if (!PyMapping_Check(env)) {
5219 +               PyErr_SetString(PyExc_TypeError,
5220 +                               "execve() arg 3 must be a mapping object");
5221 +               goto fail_0;
5222 +       }
5223 +
5224 +       argvlist = PyMem_NEW(char *, argc+1);
5225 +       if (argvlist == NULL) {
5226 +               PyErr_NoMemory();
5227 +               goto fail_0;
5228 +       }
5229 +       for (i = 0; i < argc; i++) {
5230 +               if (!PyArg_Parse((*getitem)(argv, i),
5231 +                                "et;execve() arg 2 must contain only strings",
5232 +                                Py_FileSystemDefaultEncoding,
5233 +                                &argvlist[i]))
5234 +               {
5235 +                       lastarg = i;
5236 +                       goto fail_1;
5237 +               }
5238 +       }
5239 +       lastarg = argc;
5240 +       argvlist[argc] = NULL;
5241 +
5242 +       i = PyMapping_Size(env);
5243 +       if (i < 0)
5244 +               goto fail_1;
5245 +       envlist = PyMem_NEW(char *, i + 1);
5246 +       if (envlist == NULL) {
5247 +               PyErr_NoMemory();
5248 +               goto fail_1;
5249 +       }
5250 +       envc = 0;
5251 +       keys = PyMapping_Keys(env);
5252 +       vals = PyMapping_Values(env);
5253 +       if (!keys || !vals)
5254 +               goto fail_2;
5255 +       if (!PyList_Check(keys) || !PyList_Check(vals)) {
5256 +               PyErr_SetString(PyExc_TypeError,
5257 +                       "execve(): env.keys() or env.values() is not a list");
5258 +               goto fail_2;
5259 +       }
5260 +
5261 +       for (pos = 0; pos < i; pos++) {
5262 +               char *p, *k, *v;
5263 +               size_t len;
5264 +
5265 +               key = PyList_GetItem(keys, pos);
5266 +               val = PyList_GetItem(vals, pos);
5267 +               if (!key || !val)
5268 +                       goto fail_2;
5269 +
5270 +               if (!PyArg_Parse(
5271 +                           key,
5272 +                           "s;execve() arg 3 contains a non-string key",
5273 +                           &k) ||
5274 +                   !PyArg_Parse(
5275 +                           val,
5276 +                           "s;execve() arg 3 contains a non-string value",
5277 +                           &v))
5278 +               {
5279 +                       goto fail_2;
5280 +               }
5281 +
5282 +#if defined(PYOS_OS2)
5283 +        /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
5284 +        if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
5285 +#endif
5286 +               len = PyString_Size(key) + PyString_Size(val) + 2;
5287 +               p = PyMem_NEW(char, len);
5288 +               if (p == NULL) {
5289 +                       PyErr_NoMemory();
5290 +                       goto fail_2;
5291 +               }
5292 +               PyOS_snprintf(p, len, "%s=%s", k, v);
5293 +               envlist[envc++] = p;
5294 +#if defined(PYOS_OS2)
5295 +    }
5296 +#endif
5297 +       }
5298 +       envlist[envc] = 0;
5299 +
5300 +       execve(path, argvlist, envlist);
5301 +
5302 +       /* If we get here it's definitely an error */
5303 +
5304 +       (void) posix_error();
5305 +
5306 +  fail_2:
5307 +       while (--envc >= 0)
5308 +               PyMem_DEL(envlist[envc]);
5309 +       PyMem_DEL(envlist);
5310 +  fail_1:
5311 +       free_string_array(argvlist, lastarg);
5312 +       Py_XDECREF(vals);
5313 +       Py_XDECREF(keys);
5314 +  fail_0:
5315 +       PyMem_Free(path);
5316 +       return NULL;
5317 +}
5318 +#endif /* HAVE_EXECV */
5319 +
5320 +
5321 +#ifdef HAVE_SPAWNV
5322 +PyDoc_STRVAR(posix_spawnv__doc__,
5323 +"spawnv(mode, path, args)\n\n\
5324 +Execute the program 'path' in a new process.\n\
5325 +\n\
5326 +       mode: mode of process creation\n\
5327 +       path: path of executable file\n\
5328 +       args: tuple or list of strings");
5329 +
5330 +static PyObject *
5331 +posix_spawnv(PyObject *self, PyObject *args)
5332 +{
5333 +       char *path;
5334 +       PyObject *argv;
5335 +       char **argvlist;
5336 +       int mode, i;
5337 +       Py_ssize_t argc;
5338 +       Py_intptr_t spawnval;
5339 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5340 +
5341 +       /* spawnv has three arguments: (mode, path, argv), where
5342 +          argv is a list or tuple of strings. */
5343 +
5344 +       if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
5345 +                             Py_FileSystemDefaultEncoding,
5346 +                             &path, &argv))
5347 +               return NULL;
5348 +       if (PyList_Check(argv)) {
5349 +               argc = PyList_Size(argv);
5350 +               getitem = PyList_GetItem;
5351 +       }
5352 +       else if (PyTuple_Check(argv)) {
5353 +               argc = PyTuple_Size(argv);
5354 +               getitem = PyTuple_GetItem;
5355 +       }
5356 +       else {
5357 +               PyErr_SetString(PyExc_TypeError,
5358 +                               "spawnv() arg 2 must be a tuple or list");
5359 +               PyMem_Free(path);
5360 +               return NULL;
5361 +       }
5362 +
5363 +       argvlist = PyMem_NEW(char *, argc+1);
5364 +       if (argvlist == NULL) {
5365 +               PyMem_Free(path);
5366 +               return PyErr_NoMemory();
5367 +       }
5368 +       for (i = 0; i < argc; i++) {
5369 +               if (!PyArg_Parse((*getitem)(argv, i), "et",
5370 +                                Py_FileSystemDefaultEncoding,
5371 +                                &argvlist[i])) {
5372 +                       free_string_array(argvlist, i);
5373 +                       PyErr_SetString(
5374 +                               PyExc_TypeError,
5375 +                               "spawnv() arg 2 must contain only strings");
5376 +                       PyMem_Free(path);
5377 +                       return NULL;
5378 +               }
5379 +       }
5380 +       argvlist[argc] = NULL;
5381 +
5382 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
5383 +       Py_BEGIN_ALLOW_THREADS
5384 +       spawnval = spawnv(mode, path, argvlist);
5385 +       Py_END_ALLOW_THREADS
5386 +#else
5387 +       if (mode == _OLD_P_OVERLAY)
5388 +               mode = _P_OVERLAY;
5389 +
5390 +       Py_BEGIN_ALLOW_THREADS
5391 +       spawnval = _spawnv(mode, path, argvlist);
5392 +       Py_END_ALLOW_THREADS
5393 +#endif
5394 +
5395 +       free_string_array(argvlist, argc);
5396 +       PyMem_Free(path);
5397 +
5398 +       if (spawnval == -1)
5399 +               return posix_error();
5400 +       else
5401 +#if SIZEOF_LONG == SIZEOF_VOID_P
5402 +               return Py_BuildValue("l", (long) spawnval);
5403 +#else
5404 +               return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
5405 +#endif
5406 +}
5407 +
5408 +
5409 +PyDoc_STRVAR(posix_spawnve__doc__,
5410 +"spawnve(mode, path, args, env)\n\n\
5411 +Execute the program 'path' in a new process.\n\
5412 +\n\
5413 +       mode: mode of process creation\n\
5414 +       path: path of executable file\n\
5415 +       args: tuple or list of arguments\n\
5416 +       env: dictionary of strings mapping to strings");
5417 +
5418 +static PyObject *
5419 +posix_spawnve(PyObject *self, PyObject *args)
5420 +{
5421 +       char *path;
5422 +       PyObject *argv, *env;
5423 +       char **argvlist;
5424 +       char **envlist;
5425 +       PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
5426 +       int mode, pos, envc;
5427 +       Py_ssize_t argc, i;
5428 +       Py_intptr_t spawnval;
5429 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5430 +       Py_ssize_t lastarg = 0;
5431 +
5432 +       /* spawnve has four arguments: (mode, path, argv, env), where
5433 +          argv is a list or tuple of strings and env is a dictionary
5434 +          like posix.environ. */
5435 +
5436 +       if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
5437 +                             Py_FileSystemDefaultEncoding,
5438 +                             &path, &argv, &env))
5439 +               return NULL;
5440 +       if (PyList_Check(argv)) {
5441 +               argc = PyList_Size(argv);
5442 +               getitem = PyList_GetItem;
5443 +       }
5444 +       else if (PyTuple_Check(argv)) {
5445 +               argc = PyTuple_Size(argv);
5446 +               getitem = PyTuple_GetItem;
5447 +       }
5448 +       else {
5449 +               PyErr_SetString(PyExc_TypeError,
5450 +                               "spawnve() arg 2 must be a tuple or list");
5451 +               goto fail_0;
5452 +       }
5453 +       if (!PyMapping_Check(env)) {
5454 +               PyErr_SetString(PyExc_TypeError,
5455 +                               "spawnve() arg 3 must be a mapping object");
5456 +               goto fail_0;
5457 +       }
5458 +
5459 +       argvlist = PyMem_NEW(char *, argc+1);
5460 +       if (argvlist == NULL) {
5461 +               PyErr_NoMemory();
5462 +               goto fail_0;
5463 +       }
5464 +       for (i = 0; i < argc; i++) {
5465 +               if (!PyArg_Parse((*getitem)(argv, i),
5466 +                            "et;spawnve() arg 2 must contain only strings",
5467 +                                Py_FileSystemDefaultEncoding,
5468 +                                &argvlist[i]))
5469 +               {
5470 +                       lastarg = i;
5471 +                       goto fail_1;
5472 +               }
5473 +       }
5474 +       lastarg = argc;
5475 +       argvlist[argc] = NULL;
5476 +
5477 +       i = PyMapping_Size(env);
5478 +       if (i < 0)
5479 +               goto fail_1;
5480 +       envlist = PyMem_NEW(char *, i + 1);
5481 +       if (envlist == NULL) {
5482 +               PyErr_NoMemory();
5483 +               goto fail_1;
5484 +       }
5485 +       envc = 0;
5486 +       keys = PyMapping_Keys(env);
5487 +       vals = PyMapping_Values(env);
5488 +       if (!keys || !vals)
5489 +               goto fail_2;
5490 +       if (!PyList_Check(keys) || !PyList_Check(vals)) {
5491 +               PyErr_SetString(PyExc_TypeError,
5492 +                       "spawnve(): env.keys() or env.values() is not a list");
5493 +               goto fail_2;
5494 +       }
5495 +
5496 +       for (pos = 0; pos < i; pos++) {
5497 +               char *p, *k, *v;
5498 +               size_t len;
5499 +
5500 +               key = PyList_GetItem(keys, pos);
5501 +               val = PyList_GetItem(vals, pos);
5502 +               if (!key || !val)
5503 +                       goto fail_2;
5504 +
5505 +               if (!PyArg_Parse(
5506 +                           key,
5507 +                           "s;spawnve() arg 3 contains a non-string key",
5508 +                           &k) ||
5509 +                   !PyArg_Parse(
5510 +                           val,
5511 +                           "s;spawnve() arg 3 contains a non-string value",
5512 +                           &v))
5513 +               {
5514 +                       goto fail_2;
5515 +               }
5516 +               len = PyString_Size(key) + PyString_Size(val) + 2;
5517 +               p = PyMem_NEW(char, len);
5518 +               if (p == NULL) {
5519 +                       PyErr_NoMemory();
5520 +                       goto fail_2;
5521 +               }
5522 +               PyOS_snprintf(p, len, "%s=%s", k, v);
5523 +               envlist[envc++] = p;
5524 +       }
5525 +       envlist[envc] = 0;
5526 +
5527 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
5528 +       Py_BEGIN_ALLOW_THREADS
5529 +       spawnval = spawnve(mode, path, argvlist, envlist);
5530 +       Py_END_ALLOW_THREADS
5531 +#else
5532 +       if (mode == _OLD_P_OVERLAY)
5533 +               mode = _P_OVERLAY;
5534 +
5535 +       Py_BEGIN_ALLOW_THREADS
5536 +       spawnval = _spawnve(mode, path, argvlist, envlist);
5537 +       Py_END_ALLOW_THREADS
5538 +#endif
5539 +
5540 +       if (spawnval == -1)
5541 +               (void) posix_error();
5542 +       else
5543 +#if SIZEOF_LONG == SIZEOF_VOID_P
5544 +               res = Py_BuildValue("l", (long) spawnval);
5545 +#else
5546 +               res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
5547 +#endif
5548 +
5549 +  fail_2:
5550 +       while (--envc >= 0)
5551 +               PyMem_DEL(envlist[envc]);
5552 +       PyMem_DEL(envlist);
5553 +  fail_1:
5554 +       free_string_array(argvlist, lastarg);
5555 +       Py_XDECREF(vals);
5556 +       Py_XDECREF(keys);
5557 +  fail_0:
5558 +       PyMem_Free(path);
5559 +       return res;
5560 +}
5561 +
5562 +/* OS/2 supports spawnvp & spawnvpe natively */
5563 +#if defined(PYOS_OS2)
5564 +PyDoc_STRVAR(posix_spawnvp__doc__,
5565 +"spawnvp(mode, file, args)\n\n\
5566 +Execute the program 'file' in a new process, using the environment\n\
5567 +search path to find the file.\n\
5568 +\n\
5569 +       mode: mode of process creation\n\
5570 +       file: executable file name\n\
5571 +       args: tuple or list of strings");
5572 +
5573 +static PyObject *
5574 +posix_spawnvp(PyObject *self, PyObject *args)
5575 +{
5576 +       char *path;
5577 +       PyObject *argv;
5578 +       char **argvlist;
5579 +       int mode, i, argc;
5580 +       Py_intptr_t spawnval;
5581 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5582 +
5583 +       /* spawnvp has three arguments: (mode, path, argv), where
5584 +          argv is a list or tuple of strings. */
5585 +
5586 +       if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
5587 +                             Py_FileSystemDefaultEncoding,
5588 +                             &path, &argv))
5589 +               return NULL;
5590 +       if (PyList_Check(argv)) {
5591 +               argc = PyList_Size(argv);
5592 +               getitem = PyList_GetItem;
5593 +       }
5594 +       else if (PyTuple_Check(argv)) {
5595 +               argc = PyTuple_Size(argv);
5596 +               getitem = PyTuple_GetItem;
5597 +       }
5598 +       else {
5599 +               PyErr_SetString(PyExc_TypeError,
5600 +                               "spawnvp() arg 2 must be a tuple or list");
5601 +               PyMem_Free(path);
5602 +               return NULL;
5603 +       }
5604 +
5605 +       argvlist = PyMem_NEW(char *, argc+1);
5606 +       if (argvlist == NULL) {
5607 +               PyMem_Free(path);
5608 +               return PyErr_NoMemory();
5609 +       }
5610 +       for (i = 0; i < argc; i++) {
5611 +               if (!PyArg_Parse((*getitem)(argv, i), "et",
5612 +                                Py_FileSystemDefaultEncoding,
5613 +                                &argvlist[i])) {
5614 +                       free_string_array(argvlist, i);
5615 +                       PyErr_SetString(
5616 +                               PyExc_TypeError,
5617 +                               "spawnvp() arg 2 must contain only strings");
5618 +                       PyMem_Free(path);
5619 +                       return NULL;
5620 +               }
5621 +       }
5622 +       argvlist[argc] = NULL;
5623 +
5624 +       Py_BEGIN_ALLOW_THREADS
5625 +#if defined(PYCC_GCC)
5626 +       spawnval = spawnvp(mode, path, argvlist);
5627 +#else
5628 +       spawnval = _spawnvp(mode, path, argvlist);
5629 +#endif
5630 +       Py_END_ALLOW_THREADS
5631 +
5632 +       free_string_array(argvlist, argc);
5633 +       PyMem_Free(path);
5634 +
5635 +       if (spawnval == -1)
5636 +               return posix_error();
5637 +       else
5638 +               return Py_BuildValue("l", (long) spawnval);
5639 +}
5640 +
5641 +
5642 +PyDoc_STRVAR(posix_spawnvpe__doc__,
5643 +"spawnvpe(mode, file, args, env)\n\n\
5644 +Execute the program 'file' in a new process, using the environment\n\
5645 +search path to find the file.\n\
5646 +\n\
5647 +       mode: mode of process creation\n\
5648 +       file: executable file name\n\
5649 +       args: tuple or list of arguments\n\
5650 +       env: dictionary of strings mapping to strings");
5651 +
5652 +static PyObject *
5653 +posix_spawnvpe(PyObject *self, PyObject *args)
5654 +{
5655 +       char *path;
5656 +       PyObject *argv, *env;
5657 +       char **argvlist;
5658 +       char **envlist;
5659 +       PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
5660 +       int mode, i, pos, argc, envc;
5661 +       Py_intptr_t spawnval;
5662 +       PyObject *(*getitem)(PyObject *, Py_ssize_t);
5663 +       int lastarg = 0;
5664 +
5665 +       /* spawnvpe has four arguments: (mode, path, argv, env), where
5666 +          argv is a list or tuple of strings and env is a dictionary
5667 +          like posix.environ. */
5668 +
5669 +       if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5670 +                             Py_FileSystemDefaultEncoding,
5671 +                             &path, &argv, &env))
5672 +               return NULL;
5673 +       if (PyList_Check(argv)) {
5674 +               argc = PyList_Size(argv);
5675 +               getitem = PyList_GetItem;
5676 +       }
5677 +       else if (PyTuple_Check(argv)) {
5678 +               argc = PyTuple_Size(argv);
5679 +               getitem = PyTuple_GetItem;
5680 +       }
5681 +       else {
5682 +               PyErr_SetString(PyExc_TypeError,
5683 +                               "spawnvpe() arg 2 must be a tuple or list");
5684 +               goto fail_0;
5685 +       }
5686 +       if (!PyMapping_Check(env)) {
5687 +               PyErr_SetString(PyExc_TypeError,
5688 +                               "spawnvpe() arg 3 must be a mapping object");
5689 +               goto fail_0;
5690 +       }
5691 +
5692 +       argvlist = PyMem_NEW(char *, argc+1);
5693 +       if (argvlist == NULL) {
5694 +               PyErr_NoMemory();
5695 +               goto fail_0;
5696 +       }
5697 +       for (i = 0; i < argc; i++) {
5698 +               if (!PyArg_Parse((*getitem)(argv, i),
5699 +                            "et;spawnvpe() arg 2 must contain only strings",
5700 +                                Py_FileSystemDefaultEncoding,
5701 +                                &argvlist[i]))
5702 +               {
5703 +                       lastarg = i;
5704 +                       goto fail_1;
5705 +               }
5706 +       }
5707 +       lastarg = argc;
5708 +       argvlist[argc] = NULL;
5709 +
5710 +       i = PyMapping_Size(env);
5711 +       if (i < 0)
5712 +               goto fail_1;
5713 +       envlist = PyMem_NEW(char *, i + 1);
5714 +       if (envlist == NULL) {
5715 +               PyErr_NoMemory();
5716 +               goto fail_1;
5717 +       }
5718 +       envc = 0;
5719 +       keys = PyMapping_Keys(env);
5720 +       vals = PyMapping_Values(env);
5721 +       if (!keys || !vals)
5722 +               goto fail_2;
5723 +       if (!PyList_Check(keys) || !PyList_Check(vals)) {
5724 +               PyErr_SetString(PyExc_TypeError,
5725 +                       "spawnvpe(): env.keys() or env.values() is not a list");
5726 +               goto fail_2;
5727 +       }
5728 +
5729 +       for (pos = 0; pos < i; pos++) {
5730 +               char *p, *k, *v;
5731 +               size_t len;
5732 +
5733 +               key = PyList_GetItem(keys, pos);
5734 +               val = PyList_GetItem(vals, pos);
5735 +               if (!key || !val)
5736 +                       goto fail_2;
5737 +
5738 +               if (!PyArg_Parse(
5739 +                           key,
5740 +                           "s;spawnvpe() arg 3 contains a non-string key",
5741 +                           &k) ||
5742 +                   !PyArg_Parse(
5743 +                           val,
5744 +                           "s;spawnvpe() arg 3 contains a non-string value",
5745 +                           &v))
5746 +               {
5747 +                       goto fail_2;
5748 +               }
5749 +               len = PyString_Size(key) + PyString_Size(val) + 2;
5750 +               p = PyMem_NEW(char, len);
5751 +               if (p == NULL) {
5752 +                       PyErr_NoMemory();
5753 +                       goto fail_2;
5754 +               }
5755 +               PyOS_snprintf(p, len, "%s=%s", k, v);
5756 +               envlist[envc++] = p;
5757 +       }
5758 +       envlist[envc] = 0;
5759 +
5760 +       Py_BEGIN_ALLOW_THREADS
5761 +#if defined(PYCC_GCC)
5762 +       spawnval = spawnvpe(mode, path, argvlist, envlist);
5763 +#else
5764 +       spawnval = _spawnvpe(mode, path, argvlist, envlist);
5765 +#endif
5766 +       Py_END_ALLOW_THREADS
5767 +
5768 +       if (spawnval == -1)
5769 +               (void) posix_error();
5770 +       else
5771 +               res = Py_BuildValue("l", (long) spawnval);
5772 +
5773 +  fail_2:
5774 +       while (--envc >= 0)
5775 +               PyMem_DEL(envlist[envc]);
5776 +       PyMem_DEL(envlist);
5777 +  fail_1:
5778 +       free_string_array(argvlist, lastarg);
5779 +       Py_XDECREF(vals);
5780 +       Py_XDECREF(keys);
5781 +  fail_0:
5782 +       PyMem_Free(path);
5783 +       return res;
5784 +}
5785 +#endif /* PYOS_OS2 */
5786 +#endif /* HAVE_SPAWNV */
5787 +
5788 +
5789 +#ifdef HAVE_FORK1
5790 +PyDoc_STRVAR(posix_fork1__doc__,
5791 +"fork1() -> pid\n\n\
5792 +Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5793 +\n\
5794 +Return 0 to child process and PID of child to parent process.");
5795 +
5796 +static PyObject *
5797 +posix_fork1(PyObject *self, PyObject *noargs)
5798 +{
5799 +       int pid = fork1();
5800 +       if (pid == -1)
5801 +               return posix_error();
5802 +       PyOS_AfterFork();
5803 +       return PyInt_FromLong((long)pid);
5804 +}
5805 +#endif
5806 +
5807 +
5808 +#ifdef HAVE_FORK
5809 +PyDoc_STRVAR(posix_fork__doc__,
5810 +"fork() -> pid\n\n\
5811 +Fork a child process.\n\
5812 +Return 0 to child process and PID of child to parent process.");
5813 +
5814 +static PyObject *
5815 +posix_fork(PyObject *self, PyObject *noargs)
5816 +{
5817 +       int pid = fork();
5818 +       if (pid == -1)
5819 +               return posix_error();
5820 +       if (pid == 0)
5821 +               PyOS_AfterFork();
5822 +       return PyInt_FromLong((long)pid);
5823 +}
5824 +#endif
5825 +
5826 +/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
5827 +/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5828 +#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
5829 +#define DEV_PTY_FILE "/dev/ptc"
5830 +#define HAVE_DEV_PTMX
5831 +#else
5832 +#define DEV_PTY_FILE "/dev/ptmx"
5833 +#endif
5834 +
5835 +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
5836 +#ifdef HAVE_PTY_H
5837 +#include <pty.h>
5838 +#else
5839 +#ifdef HAVE_LIBUTIL_H
5840 +#include <libutil.h>
5841 +#endif /* HAVE_LIBUTIL_H */
5842 +#endif /* HAVE_PTY_H */
5843 +#ifdef HAVE_STROPTS_H
5844 +#include <stropts.h>
5845 +#endif
5846 +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
5847 +
5848 +#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
5849 +PyDoc_STRVAR(posix_openpty__doc__,
5850 +"openpty() -> (master_fd, slave_fd)\n\n\
5851 +Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
5852 +
5853 +static PyObject *
5854 +posix_openpty(PyObject *self, PyObject *noargs)
5855 +{
5856 +       int master_fd, slave_fd;
5857 +#ifndef HAVE_OPENPTY
5858 +       char * slave_name;
5859 +#endif
5860 +#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
5861 +       PyOS_sighandler_t sig_saved;
5862 +#ifdef sun
5863 +       extern char *ptsname(int fildes);
5864 +#endif
5865 +#endif
5866 +
5867 +#ifdef HAVE_OPENPTY
5868 +       if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5869 +               return posix_error();
5870 +#elif defined(HAVE__GETPTY)
5871 +       slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5872 +       if (slave_name == NULL)
5873 +               return posix_error();
5874 +
5875 +       slave_fd = open(slave_name, O_RDWR);
5876 +       if (slave_fd < 0)
5877 +               return posix_error();
5878 +#else
5879 +       master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5880 +       if (master_fd < 0)
5881 +               return posix_error();
5882 +       sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5883 +       /* change permission of slave */
5884 +       if (grantpt(master_fd) < 0) {
5885 +               PyOS_setsig(SIGCHLD, sig_saved);
5886 +               return posix_error();
5887 +       }
5888 +       /* unlock slave */
5889 +       if (unlockpt(master_fd) < 0) {
5890 +               PyOS_setsig(SIGCHLD, sig_saved);
5891 +               return posix_error();
5892 +       }
5893 +       PyOS_setsig(SIGCHLD, sig_saved);
5894 +       slave_name = ptsname(master_fd); /* get name of slave */
5895 +       if (slave_name == NULL)
5896 +               return posix_error();
5897 +       slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5898 +       if (slave_fd < 0)
5899 +               return posix_error();
5900 +#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
5901 +       ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5902 +       ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
5903 +#ifndef __hpux
5904 +       ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
5905 +#endif /* __hpux */
5906 +#endif /* HAVE_CYGWIN */
5907 +#endif /* HAVE_OPENPTY */
5908 +
5909 +       return Py_BuildValue("(ii)", master_fd, slave_fd);
5910 +
5911 +}
5912 +#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
5913 +
5914 +#ifdef HAVE_FORKPTY
5915 +PyDoc_STRVAR(posix_forkpty__doc__,
5916 +"forkpty() -> (pid, master_fd)\n\n\
5917 +Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5918 +Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
5919 +To both, return fd of newly opened pseudo-terminal.\n");
5920 +
5921 +static PyObject *
5922 +posix_forkpty(PyObject *self, PyObject *noargs)
5923 +{
5924 +       int master_fd = -1, pid;
5925 +
5926 +       pid = forkpty(&master_fd, NULL, NULL, NULL);
5927 +       if (pid == -1)
5928 +               return posix_error();
5929 +       if (pid == 0)
5930 +               PyOS_AfterFork();
5931 +       return Py_BuildValue("(ii)", pid, master_fd);
5932 +}
5933 +#endif
5934 +
5935 +#ifdef HAVE_GETEGID
5936 +PyDoc_STRVAR(posix_getegid__doc__,
5937 +"getegid() -> egid\n\n\
5938 +Return the current process's effective group id.");
5939 +
5940 +static PyObject *
5941 +posix_getegid(PyObject *self, PyObject *noargs)
5942 +{
5943 +       return PyInt_FromLong((long)getegid());
5944 +}
5945 +#endif
5946 +
5947 +
5948 +#ifdef HAVE_GETEUID
5949 +PyDoc_STRVAR(posix_geteuid__doc__,
5950 +"geteuid() -> euid\n\n\
5951 +Return the current process's effective user id.");
5952 +
5953 +static PyObject *
5954 +posix_geteuid(PyObject *self, PyObject *noargs)
5955 +{
5956 +       return PyInt_FromLong((long)geteuid());
5957 +}
5958 +#endif
5959 +
5960 +
5961 +#ifdef HAVE_GETGID
5962 +PyDoc_STRVAR(posix_getgid__doc__,
5963 +"getgid() -> gid\n\n\
5964 +Return the current process's group id.");
5965 +
5966 +static PyObject *
5967 +posix_getgid(PyObject *self, PyObject *noargs)
5968 +{
5969 +       return PyInt_FromLong((long)getgid());
5970 +}
5971 +#endif
5972 +
5973 +
5974 +PyDoc_STRVAR(posix_getpid__doc__,
5975 +"getpid() -> pid\n\n\
5976 +Return the current process id");
5977 +
5978 +static PyObject *
5979 +posix_getpid(PyObject *self, PyObject *noargs)
5980 +{
5981 +       return PyInt_FromLong((long)getpid());
5982 +}
5983 +
5984 +
5985 +#ifdef HAVE_GETGROUPS
5986 +PyDoc_STRVAR(posix_getgroups__doc__,
5987 +"getgroups() -> list of group IDs\n\n\
5988 +Return list of supplemental group IDs for the process.");
5989 +
5990 +static PyObject *
5991 +posix_getgroups(PyObject *self, PyObject *noargs)
5992 +{
5993 +    PyObject *result = NULL;
5994 +
5995 +#ifdef NGROUPS_MAX
5996 +#define MAX_GROUPS NGROUPS_MAX
5997 +#else
5998 +        /* defined to be 16 on Solaris7, so this should be a small number */
5999 +#define MAX_GROUPS 64
6000 +#endif
6001 +        gid_t grouplist[MAX_GROUPS];
6002 +        int n;
6003 +
6004 +        n = getgroups(MAX_GROUPS, grouplist);
6005 +        if (n < 0)
6006 +            posix_error();
6007 +        else {
6008 +            result = PyList_New(n);
6009 +            if (result != NULL) {
6010 +                int i;
6011 +                for (i = 0; i < n; ++i) {
6012 +                    PyObject *o = PyInt_FromLong((long)grouplist[i]);
6013 +                    if (o == NULL) {
6014 +                        Py_DECREF(result);
6015 +                        result = NULL;
6016 +                        break;
6017 +                    }
6018 +                    PyList_SET_ITEM(result, i, o);
6019 +                }
6020 +            }
6021 +        }
6022 +
6023 +    return result;
6024 +}
6025 +#endif
6026 +
6027 +#ifdef HAVE_GETPGID
6028 +PyDoc_STRVAR(posix_getpgid__doc__,
6029 +"getpgid(pid) -> pgid\n\n\
6030 +Call the system call getpgid().");
6031 +
6032 +static PyObject *
6033 +posix_getpgid(PyObject *self, PyObject *args)
6034 +{
6035 +       int pid, pgid;
6036 +       if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
6037 +               return NULL;
6038 +       pgid = getpgid(pid);
6039 +       if (pgid < 0)
6040 +               return posix_error();
6041 +       return PyInt_FromLong((long)pgid);
6042 +}
6043 +#endif /* HAVE_GETPGID */
6044 +
6045 +
6046 +#ifdef HAVE_GETPGRP
6047 +PyDoc_STRVAR(posix_getpgrp__doc__,
6048 +"getpgrp() -> pgrp\n\n\
6049 +Return the current process group id.");
6050 +
6051 +static PyObject *
6052 +posix_getpgrp(PyObject *self, PyObject *noargs)
6053 +{
6054 +#ifdef GETPGRP_HAVE_ARG
6055 +       return PyInt_FromLong((long)getpgrp(0));
6056 +#else /* GETPGRP_HAVE_ARG */
6057 +       return PyInt_FromLong((long)getpgrp());
6058 +#endif /* GETPGRP_HAVE_ARG */
6059 +}
6060 +#endif /* HAVE_GETPGRP */
6061 +
6062 +
6063 +#ifdef HAVE_SETPGRP
6064 +PyDoc_STRVAR(posix_setpgrp__doc__,
6065 +"setpgrp()\n\n\
6066 +Make this process a session leader.");
6067 +
6068 +static PyObject *
6069 +posix_setpgrp(PyObject *self, PyObject *noargs)
6070 +{
6071 +#ifdef SETPGRP_HAVE_ARG
6072 +       if (setpgrp(0, 0) < 0)
6073 +#else /* SETPGRP_HAVE_ARG */
6074 +       if (setpgrp() < 0)
6075 +#endif /* SETPGRP_HAVE_ARG */
6076 +               return posix_error();
6077 +       Py_INCREF(Py_None);
6078 +       return Py_None;
6079 +}
6080 +
6081 +#endif /* HAVE_SETPGRP */
6082 +
6083 +#ifdef HAVE_GETPPID
6084 +PyDoc_STRVAR(posix_getppid__doc__,
6085 +"getppid() -> ppid\n\n\
6086 +Return the parent's process id.");
6087 +
6088 +static PyObject *
6089 +posix_getppid(PyObject *self, PyObject *noargs)
6090 +{
6091 +       return PyInt_FromLong((long)getppid());
6092 +}
6093 +#endif
6094 +
6095 +
6096 +#ifdef HAVE_GETLOGIN
6097 +PyDoc_STRVAR(posix_getlogin__doc__,
6098 +"getlogin() -> string\n\n\
6099 +Return the actual login name.");
6100 +
6101 +static PyObject *
6102 +posix_getlogin(PyObject *self, PyObject *noargs)
6103 +{
6104 +        PyObject *result = NULL;
6105 +        char *name;
6106 +        int old_errno = errno;
6107 +
6108 +        errno = 0;
6109 +        name = getlogin();
6110 +        if (name == NULL) {
6111 +            if (errno)
6112 +                posix_error();
6113 +            else
6114 +                PyErr_SetString(PyExc_OSError,
6115 +                                "unable to determine login name");
6116 +        }
6117 +        else
6118 +            result = PyString_FromString(name);
6119 +        errno = old_errno;
6120 +
6121 +    return result;
6122 +}
6123 +#endif
6124 +
6125 +#ifdef HAVE_GETUID
6126 +PyDoc_STRVAR(posix_getuid__doc__,
6127 +"getuid() -> uid\n\n\
6128 +Return the current process's user id.");
6129 +
6130 +static PyObject *
6131 +posix_getuid(PyObject *self, PyObject *noargs)
6132 +{
6133 +       return PyInt_FromLong((long)getuid());
6134 +}
6135 +#endif
6136 +
6137 +
6138 +#ifdef HAVE_KILL
6139 +PyDoc_STRVAR(posix_kill__doc__,
6140 +"kill(pid, sig)\n\n\
6141 +Kill a process with a signal.");
6142 +
6143 +static PyObject *
6144 +posix_kill(PyObject *self, PyObject *args)
6145 +{
6146 +       int pid, sig;
6147 +       if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
6148 +               return NULL;
6149 +#if defined(PYOS_OS2) && !defined(PYCC_GCC)
6150 +    if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6151 +        APIRET rc;
6152 +        if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
6153 +            return os2_error(rc);
6154 +
6155 +    } else if (sig == XCPT_SIGNAL_KILLPROC) {
6156 +        APIRET rc;
6157 +        if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
6158 +            return os2_error(rc);
6159 +
6160 +    } else
6161 +        return NULL; /* Unrecognized Signal Requested */
6162 +#else
6163 +       if (kill(pid, sig) == -1)
6164 +               return posix_error();
6165 +#endif
6166 +       Py_INCREF(Py_None);
6167 +       return Py_None;
6168 +}
6169 +#endif
6170 +
6171 +#ifdef HAVE_KILLPG
6172 +PyDoc_STRVAR(posix_killpg__doc__,
6173 +"killpg(pgid, sig)\n\n\
6174 +Kill a process group with a signal.");
6175 +
6176 +static PyObject *
6177 +posix_killpg(PyObject *self, PyObject *args)
6178 +{
6179 +       int pgid, sig;
6180 +       if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
6181 +               return NULL;
6182 +       if (killpg(pgid, sig) == -1)
6183 +               return posix_error();
6184 +       Py_INCREF(Py_None);
6185 +       return Py_None;
6186 +}
6187 +#endif
6188 +
6189 +#ifdef HAVE_PLOCK
6190 +
6191 +#ifdef HAVE_SYS_LOCK_H
6192 +#include <sys/lock.h>
6193 +#endif
6194 +
6195 +PyDoc_STRVAR(posix_plock__doc__,
6196 +"plock(op)\n\n\
6197 +Lock program segments into memory.");
6198 +
6199 +static PyObject *
6200 +posix_plock(PyObject *self, PyObject *args)
6201 +{
6202 +       int op;
6203 +       if (!PyArg_ParseTuple(args, "i:plock", &op))
6204 +               return NULL;
6205 +       if (plock(op) == -1)
6206 +               return posix_error();
6207 +       Py_INCREF(Py_None);
6208 +       return Py_None;
6209 +}
6210 +#endif
6211 +
6212 +
6213 +#ifdef HAVE_POPEN
6214 +PyDoc_STRVAR(posix_popen__doc__,
6215 +"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
6216 +Open a pipe to/from a command returning a file object.");
6217 +
6218 +#if defined(PYOS_OS2)
6219 +#if defined(PYCC_VACPP)
6220 +static int
6221 +async_system(const char *command)
6222 +{
6223 +       char errormsg[256], args[1024];
6224 +       RESULTCODES rcodes;
6225 +       APIRET rc;
6226 +
6227 +       char *shell = getenv("COMSPEC");
6228 +       if (!shell)
6229 +               shell = "cmd";
6230 +
6231 +       /* avoid overflowing the argument buffer */
6232 +       if (strlen(shell) + 3 + strlen(command) >= 1024)
6233 +               return ERROR_NOT_ENOUGH_MEMORY
6234 +
6235 +       args[0] = '\0';
6236 +       strcat(args, shell);
6237 +       strcat(args, "/c ");
6238 +       strcat(args, command);
6239 +
6240 +       /* execute asynchronously, inheriting the environment */
6241 +       rc = DosExecPgm(errormsg,
6242 +                       sizeof(errormsg),
6243 +                       EXEC_ASYNC,
6244 +                       args,
6245 +                       NULL,
6246 +                       &rcodes,
6247 +                       shell);
6248 +       return rc;
6249 +}
6250 +
6251 +static FILE *
6252 +popen(const char *command, const char *mode, int pipesize, int *err)
6253 +{
6254 +       int oldfd, tgtfd;
6255 +       HFILE pipeh[2];
6256 +       APIRET rc;
6257 +
6258 +       /* mode determines which of stdin or stdout is reconnected to
6259 +        * the pipe to the child
6260 +        */
6261 +       if (strchr(mode, 'r') != NULL) {
6262 +               tgt_fd = 1;     /* stdout */
6263 +       } else if (strchr(mode, 'w')) {
6264 +               tgt_fd = 0;     /* stdin */
6265 +       } else {
6266 +               *err = ERROR_INVALID_ACCESS;
6267 +               return NULL;
6268 +       }
6269 +
6270 +       /* setup the pipe */
6271 +       if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
6272 +               *err = rc;
6273 +               return NULL;
6274 +       }
6275 +
6276 +       /* prevent other threads accessing stdio */
6277 +       DosEnterCritSec();
6278 +
6279 +       /* reconnect stdio and execute child */
6280 +       oldfd = dup(tgtfd);
6281 +       close(tgtfd);
6282 +       if (dup2(pipeh[tgtfd], tgtfd) == 0) {
6283 +               DosClose(pipeh[tgtfd]);
6284 +               rc = async_system(command);
6285 +       }
6286 +
6287 +       /* restore stdio */
6288 +       dup2(oldfd, tgtfd);
6289 +       close(oldfd);
6290 +
6291 +       /* allow other threads access to stdio */
6292 +       DosExitCritSec();
6293 +
6294 +       /* if execution of child was successful return file stream */
6295 +       if (rc == NO_ERROR)
6296 +               return fdopen(pipeh[1 - tgtfd], mode);
6297 +       else {
6298 +               DosClose(pipeh[1 - tgtfd]);
6299 +               *err = rc;
6300 +               return NULL;
6301 +       }
6302 +}
6303 +
6304 +static PyObject *
6305 +posix_popen(PyObject *self, PyObject *args)
6306 +{
6307 +       char *name;
6308 +       char *mode = "r";
6309 +       int   err, bufsize = -1;
6310 +       FILE *fp;
6311 +       PyObject *f;
6312 +       if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
6313 +               return NULL;
6314 +       Py_BEGIN_ALLOW_THREADS
6315 +       fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
6316 +       Py_END_ALLOW_THREADS
6317 +       if (fp == NULL)
6318 +               return os2_error(err);
6319 +
6320 +       f = PyFile_FromFile(fp, name, mode, fclose);
6321 +       if (f != NULL)
6322 +               PyFile_SetBufSize(f, bufsize);
6323 +       return f;
6324 +}
6325 +
6326 +#elif defined(PYCC_GCC)
6327 +
6328 +/* standard posix version of popen() support */
6329 +static PyObject *
6330 +posix_popen(PyObject *self, PyObject *args)
6331 +{
6332 +       char *name;
6333 +       char *mode = "r";
6334 +       int bufsize = -1;
6335 +       FILE *fp;
6336 +       PyObject *f;
6337 +       if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
6338 +               return NULL;
6339 +       Py_BEGIN_ALLOW_THREADS
6340 +       fp = popen(name, mode);
6341 +       Py_END_ALLOW_THREADS
6342 +       if (fp == NULL)
6343 +               return posix_error();
6344 +       f = PyFile_FromFile(fp, name, mode, pclose);
6345 +       if (f != NULL)
6346 +               PyFile_SetBufSize(f, bufsize);
6347 +       return f;
6348 +}
6349 +
6350 +/* fork() under OS/2 has lots'o'warts
6351 + * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
6352 + * most of this code is a ripoff of the win32 code, but using the
6353 + * capabilities of EMX's C library routines
6354 + */
6355 +
6356 +/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
6357 +#define POPEN_1 1
6358 +#define POPEN_2 2
6359 +#define POPEN_3 3
6360 +#define POPEN_4 4
6361 +
6362 +static PyObject *_PyPopen(char *, int, int, int);
6363 +static int _PyPclose(FILE *file);
6364 +
6365 +/*
6366 + * Internal dictionary mapping popen* file pointers to process handles,
6367 + * for use when retrieving the process exit code.  See _PyPclose() below
6368 + * for more information on this dictionary's use.
6369 + */
6370 +static PyObject *_PyPopenProcs = NULL;
6371 +
6372 +/* os2emx version of popen2()
6373 + *
6374 + * The result of this function is a pipe (file) connected to the
6375 + * process's stdin, and a pipe connected to the process's stdout.
6376 + */
6377 +
6378 +static PyObject *
6379 +os2emx_popen2(PyObject *self, PyObject  *args)
6380 +{
6381 +       PyObject *f;
6382 +       int tm=0;
6383 +
6384 +       char *cmdstring;
6385 +       char *mode = "t";
6386 +       int bufsize = -1;
6387 +       if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
6388 +               return NULL;
6389 +
6390 +       if (*mode == 't')
6391 +               tm = O_TEXT;
6392 +       else if (*mode != 'b') {
6393 +               PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6394 +               return NULL;
6395 +       } else
6396 +               tm = O_BINARY;
6397 +
6398 +       f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
6399 +
6400 +       return f;
6401 +}
6402 +
6403 +/*
6404 + * Variation on os2emx.popen2
6405 + *
6406 + * The result of this function is 3 pipes - the process's stdin,
6407 + * stdout and stderr
6408 + */
6409 +
6410 +static PyObject *
6411 +os2emx_popen3(PyObject *self, PyObject *args)
6412 +{
6413 +       PyObject *f;
6414 +       int tm = 0;
6415 +
6416 +       char *cmdstring;
6417 +       char *mode = "t";
6418 +       int bufsize = -1;
6419 +       if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
6420 +               return NULL;
6421 +
6422 +       if (*mode == 't')
6423 +               tm = O_TEXT;
6424 +       else if (*mode != 'b') {
6425 +               PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6426 +               return NULL;
6427 +       } else
6428 +               tm = O_BINARY;
6429 +
6430 +       f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
6431 +
6432 +       return f;
6433 +}
6434 +
6435 +/*
6436 + * Variation on os2emx.popen2
6437 + *
6438 + * The result of this function is 2 pipes - the processes stdin,
6439 + * and stdout+stderr combined as a single pipe.
6440 + */
6441 +
6442 +static PyObject *
6443 +os2emx_popen4(PyObject *self, PyObject  *args)
6444 +{
6445 +       PyObject *f;
6446 +       int tm = 0;
6447 +
6448 +       char *cmdstring;
6449 +       char *mode = "t";
6450 +       int bufsize = -1;
6451 +       if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
6452 +               return NULL;
6453 +
6454 +       if (*mode == 't')
6455 +               tm = O_TEXT;
6456 +       else if (*mode != 'b') {
6457 +               PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6458 +               return NULL;
6459 +       } else
6460 +               tm = O_BINARY;
6461 +
6462 +       f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
6463 +
6464 +       return f;
6465 +}
6466 +
6467 +/* a couple of structures for convenient handling of multiple
6468 + * file handles and pipes
6469 + */
6470 +struct file_ref
6471 +{
6472 +       int handle;
6473 +       int flags;
6474 +};
6475 +
6476 +struct pipe_ref
6477 +{
6478 +       int rd;
6479 +       int wr;
6480 +};
6481 +
6482 +/* The following code is derived from the win32 code */
6483 +
6484 +static PyObject *
6485 +_PyPopen(char *cmdstring, int mode, int n, int bufsize)
6486 +{
6487 +       struct file_ref stdio[3];
6488 +       struct pipe_ref p_fd[3];
6489 +       FILE *p_s[3];
6490 +       int file_count, i, pipe_err, pipe_pid;
6491 +       char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
6492 +       PyObject *f, *p_f[3];
6493 +
6494 +       /* file modes for subsequent fdopen's on pipe handles */
6495 +       if (mode == O_TEXT)
6496 +       {
6497 +               rd_mode = "rt";
6498 +               wr_mode = "wt";
6499 +       }
6500 +       else
6501 +       {
6502 +               rd_mode = "rb";
6503 +               wr_mode = "wb";
6504 +       }
6505 +
6506 +       /* prepare shell references */
6507 +       if ((shell = getenv("EMXSHELL")) == NULL)
6508 +               if ((shell = getenv("COMSPEC")) == NULL)
6509 +               {
6510 +                       errno = ENOENT;
6511 +                       return posix_error();
6512 +               }
6513 +
6514 +       sh_name = _getname(shell);
6515 +       if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
6516 +               opt = "/c";
6517 +       else
6518 +               opt = "-c";
6519 +
6520 +       /* save current stdio fds + their flags, and set not inheritable */
6521 +       i = pipe_err = 0;
6522 +       while (pipe_err >= 0 && i < 3)
6523 +       {
6524 +               pipe_err = stdio[i].handle = dup(i);
6525 +               stdio[i].flags = fcntl(i, F_GETFD, 0);
6526 +               fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
6527 +               i++;
6528 +       }
6529 +       if (pipe_err < 0)
6530 +       {
6531 +               /* didn't get them all saved - clean up and bail out */
6532 +               int saved_err = errno;
6533 +               while (i-- > 0)
6534 +               {
6535 +                       close(stdio[i].handle);
6536 +               }
6537 +               errno = saved_err;
6538 +               return posix_error();
6539 +       }
6540 +
6541 +       /* create pipe ends */
6542 +       file_count = 2;
6543 +       if (n == POPEN_3)
6544 +               file_count = 3;
6545 +       i = pipe_err = 0;
6546 +       while ((pipe_err == 0) && (i < file_count))
6547 +               pipe_err = pipe((int *)&p_fd[i++]);
6548 +       if (pipe_err < 0)
6549 +       {
6550 +               /* didn't get them all made - clean up and bail out */
6551 +               while (i-- > 0)
6552 +               {
6553 +                       close(p_fd[i].wr);
6554 +                       close(p_fd[i].rd);
6555 +               }
6556 +               errno = EPIPE;
6557 +               return posix_error();
6558 +       }
6559 +
6560 +       /* change the actual standard IO streams over temporarily,
6561 +        * making the retained pipe ends non-inheritable
6562 +        */
6563 +       pipe_err = 0;
6564 +
6565 +       /* - stdin */
6566 +       if (dup2(p_fd[0].rd, 0) == 0)
6567 +       {
6568 +               close(p_fd[0].rd);
6569 +               i = fcntl(p_fd[0].wr, F_GETFD, 0);
6570 +               fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
6571 +               if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
6572 +               {
6573 +                       close(p_fd[0].wr);
6574 +                       pipe_err = -1;
6575 +               }
6576 +       }
6577 +       else
6578 +       {
6579 +               pipe_err = -1;
6580 +       }
6581 +
6582 +       /* - stdout */
6583 +       if (pipe_err == 0)
6584 +       {
6585 +               if (dup2(p_fd[1].wr, 1) == 1)
6586 +               {
6587 +                       close(p_fd[1].wr);
6588 +                       i = fcntl(p_fd[1].rd, F_GETFD, 0);
6589 +                       fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
6590 +                       if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
6591 +                       {
6592 +                               close(p_fd[1].rd);
6593 +                               pipe_err = -1;
6594 +                       }
6595 +               }
6596 +               else
6597 +               {
6598 +                       pipe_err = -1;
6599 +               }
6600 +       }
6601 +
6602 +       /* - stderr, as required */
6603 +       if (pipe_err == 0)
6604 +               switch (n)
6605 +               {
6606 +                       case POPEN_3:
6607 +                       {
6608 +                               if (dup2(p_fd[2].wr, 2) == 2)
6609 +                               {
6610 +                                       close(p_fd[2].wr);
6611 +                                       i = fcntl(p_fd[2].rd, F_GETFD, 0);
6612 +                                       fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
6613 +                                       if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
6614 +                                       {
6615 +                                               close(p_fd[2].rd);
6616 +                                               pipe_err = -1;
6617 +                                       }
6618 +                               }
6619 +                               else
6620 +                               {
6621 +                                       pipe_err = -1;
6622 +                               }
6623 +                               break;
6624 +                       }
6625 +
6626 +                       case POPEN_4:
6627 +                       {
6628 +                               if (dup2(1, 2) != 2)
6629 +                               {
6630 +                                       pipe_err = -1;
6631 +                               }
6632 +                               break;
6633 +                       }
6634 +               }
6635 +
6636 +       /* spawn the child process */
6637 +       if (pipe_err == 0)
6638 +       {
6639 +               pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
6640 +               if (pipe_pid == -1)
6641 +               {
6642 +                       pipe_err = -1;
6643 +               }
6644 +               else
6645 +               {
6646 +                       /* save the PID into the FILE structure
6647 +                        * NOTE: this implementation doesn't actually
6648 +                        * take advantage of this, but do it for
6649 +                        * completeness - AIM Apr01
6650 +                        */
6651 +                       for (i = 0; i < file_count; i++)
6652 +                               p_s[i]->_pid = pipe_pid;
6653 +               }
6654 +       }
6655 +
6656 +       /* reset standard IO to normal */
6657 +       for (i = 0; i < 3; i++)
6658 +       {
6659 +               dup2(stdio[i].handle, i);
6660 +               fcntl(i, F_SETFD, stdio[i].flags);
6661 +               close(stdio[i].handle);
6662 +       }
6663 +
6664 +       /* if any remnant problems, clean up and bail out */
6665 +       if (pipe_err < 0)
6666 +       {
6667 +               for (i = 0; i < 3; i++)
6668 +               {
6669 +                       close(p_fd[i].rd);
6670 +                       close(p_fd[i].wr);
6671 +               }
6672 +               errno = EPIPE;
6673 +               return posix_error_with_filename(cmdstring);
6674 +       }
6675 +
6676 +       /* build tuple of file objects to return */
6677 +       if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
6678 +               PyFile_SetBufSize(p_f[0], bufsize);
6679 +       if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
6680 +               PyFile_SetBufSize(p_f[1], bufsize);
6681 +       if (n == POPEN_3)
6682 +       {
6683 +               if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
6684 +                       PyFile_SetBufSize(p_f[0], bufsize);
6685 +               f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
6686 +       }
6687 +       else
6688 +               f = PyTuple_Pack(2, p_f[0], p_f[1]);
6689 +
6690 +       /*
6691 +        * Insert the files we've created into the process dictionary
6692 +        * all referencing the list with the process handle and the
6693 +        * initial number of files (see description below in _PyPclose).
6694 +        * Since if _PyPclose later tried to wait on a process when all
6695 +        * handles weren't closed, it could create a deadlock with the
6696 +        * child, we spend some energy here to try to ensure that we
6697 +        * either insert all file handles into the dictionary or none
6698 +        * at all.  It's a little clumsy with the various popen modes
6699 +        * and variable number of files involved.
6700 +        */
6701 +       if (!_PyPopenProcs)
6702 +       {
6703 +               _PyPopenProcs = PyDict_New();
6704 +       }
6705 +
6706 +       if (_PyPopenProcs)
6707 +       {
6708 +               PyObject *procObj, *pidObj, *intObj, *fileObj[3];
6709 +               int ins_rc[3];
6710 +
6711 +               fileObj[0] = fileObj[1] = fileObj[2] = NULL;
6712 +               ins_rc[0]  = ins_rc[1]  = ins_rc[2]  = 0;
6713 +
6714 +               procObj = PyList_New(2);
6715 +               pidObj = PyInt_FromLong((long) pipe_pid);
6716 +               intObj = PyInt_FromLong((long) file_count);
6717 +
6718 +               if (procObj && pidObj && intObj)
6719 +               {
6720 +                       PyList_SetItem(procObj, 0, pidObj);
6721 +                       PyList_SetItem(procObj, 1, intObj);
6722 +
6723 +                       fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
6724 +                       if (fileObj[0])
6725 +                       {
6726 +                           ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
6727 +                                                      fileObj[0],
6728 +                                                      procObj);
6729 +                       }
6730 +                       fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
6731 +                       if (fileObj[1])
6732 +                       {
6733 +                           ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
6734 +                                                      fileObj[1],
6735 +                                                      procObj);
6736 +                       }
6737 +                       if (file_count >= 3)
6738 +                       {
6739 +                               fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
6740 +                               if (fileObj[2])
6741 +                               {
6742 +                                   ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
6743 +                                                              fileObj[2],
6744 +                                                              procObj);
6745 +                               }
6746 +                       }
6747 +
6748 +                       if (ins_rc[0] < 0 || !fileObj[0] ||
6749 +                           ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
6750 +                           ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
6751 +                       {
6752 +                               /* Something failed - remove any dictionary
6753 +                                * entries that did make it.
6754 +                                */
6755 +                               if (!ins_rc[0] && fileObj[0])
6756 +                               {
6757 +                                       PyDict_DelItem(_PyPopenProcs,
6758 +                                                       fileObj[0]);
6759 +                               }
6760 +                               if (!ins_rc[1] && fileObj[1])
6761 +                               {
6762 +                                       PyDict_DelItem(_PyPopenProcs,
6763 +                                                       fileObj[1]);
6764 +                               }
6765 +                               if (!ins_rc[2] && fileObj[2])
6766 +                               {
6767 +                                       PyDict_DelItem(_PyPopenProcs,
6768 +                                                       fileObj[2]);
6769 +                               }
6770 +                       }
6771 +               }
6772 +
6773 +               /*
6774 +                * Clean up our localized references for the dictionary keys
6775 +                * and value since PyDict_SetItem will Py_INCREF any copies
6776 +                * that got placed in the dictionary.
6777 +                */
6778 +               Py_XDECREF(procObj);
6779 +               Py_XDECREF(fileObj[0]);
6780 +               Py_XDECREF(fileObj[1]);
6781 +               Py_XDECREF(fileObj[2]);
6782 +       }
6783 +
6784 +       /* Child is launched. */
6785 +       return f;
6786 +}
6787 +
6788 +/*
6789 + * Wrapper for fclose() to use for popen* files, so we can retrieve the
6790 + * exit code for the child process and return as a result of the close.
6791 + *
6792 + * This function uses the _PyPopenProcs dictionary in order to map the
6793 + * input file pointer to information about the process that was
6794 + * originally created by the popen* call that created the file pointer.
6795 + * The dictionary uses the file pointer as a key (with one entry
6796 + * inserted for each file returned by the original popen* call) and a
6797 + * single list object as the value for all files from a single call.
6798 + * The list object contains the Win32 process handle at [0], and a file
6799 + * count at [1], which is initialized to the total number of file
6800 + * handles using that list.
6801 + *
6802 + * This function closes whichever handle it is passed, and decrements
6803 + * the file count in the dictionary for the process handle pointed to
6804 + * by this file.  On the last close (when the file count reaches zero),
6805 + * this function will wait for the child process and then return its
6806 + * exit code as the result of the close() operation.  This permits the
6807 + * files to be closed in any order - it is always the close() of the
6808 + * final handle that will return the exit code.
6809 + *
6810 + * NOTE: This function is currently called with the GIL released.
6811 + * hence we use the GILState API to manage our state.
6812 + */
6813 +
6814 +static int _PyPclose(FILE *file)
6815 +{
6816 +       int result;
6817 +       int exit_code;
6818 +       int pipe_pid;
6819 +       PyObject *procObj, *pidObj, *intObj, *fileObj;
6820 +       int file_count;
6821 +#ifdef WITH_THREAD
6822 +       PyGILState_STATE state;
6823 +#endif
6824 +
6825 +       /* Close the file handle first, to ensure it can't block the
6826 +        * child from exiting if it's the last handle.
6827 +        */
6828 +       result = fclose(file);
6829 +
6830 +#ifdef WITH_THREAD
6831 +       state = PyGILState_Ensure();
6832 +#endif
6833 +       if (_PyPopenProcs)
6834 +       {
6835 +               if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
6836 +                   (procObj = PyDict_GetItem(_PyPopenProcs,
6837 +                                             fileObj)) != NULL &&
6838 +                   (pidObj = PyList_GetItem(procObj,0)) != NULL &&
6839 +                   (intObj = PyList_GetItem(procObj,1)) != NULL)
6840 +               {
6841 +                       pipe_pid = (int) PyInt_AsLong(pidObj);
6842 +                       file_count = (int) PyInt_AsLong(intObj);
6843 +
6844 +                       if (file_count > 1)
6845 +                       {
6846 +                               /* Still other files referencing process */
6847 +                               file_count--;
6848 +                               PyList_SetItem(procObj,1,
6849 +                                              PyInt_FromLong((long) file_count));
6850 +                       }
6851 +                       else
6852 +                       {
6853 +                               /* Last file for this process */
6854 +                               if (result != EOF &&
6855 +                                   waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
6856 +                               {
6857 +                                       /* extract exit status */
6858 +                                       if (WIFEXITED(exit_code))
6859 +                                       {
6860 +                                               result = WEXITSTATUS(exit_code);
6861 +                                       }
6862 +                                       else
6863 +                                       {
6864 +                                               errno = EPIPE;
6865 +                                               result = -1;
6866 +                                       }
6867 +                               }
6868 +                               else
6869 +                               {
6870 +                                       /* Indicate failure - this will cause the file object
6871 +                                        * to raise an I/O error and translate the last
6872 +                                        * error code from errno.  We do have a problem with
6873 +                                        * last errors that overlap the normal errno table,
6874 +                                        * but that's a consistent problem with the file object.
6875 +                                        */
6876 +                                       result = -1;
6877 +                               }
6878 +                       }
6879 +
6880 +                       /* Remove this file pointer from dictionary */
6881 +                       PyDict_DelItem(_PyPopenProcs, fileObj);
6882 +
6883 +                       if (PyDict_Size(_PyPopenProcs) == 0)
6884 +                       {
6885 +                               Py_DECREF(_PyPopenProcs);
6886 +                               _PyPopenProcs = NULL;
6887 +                       }
6888 +
6889 +               } /* if object retrieval ok */
6890 +
6891 +               Py_XDECREF(fileObj);
6892 +       } /* if _PyPopenProcs */
6893 +
6894 +#ifdef WITH_THREAD
6895 +       PyGILState_Release(state);
6896 +#endif
6897 +       return result;
6898 +}
6899 +
6900 +#endif /* PYCC_??? */
6901 +
6902 +#elif defined(MS_WINDOWS)
6903 +
6904 +/*
6905 + * Portable 'popen' replacement for Win32.
6906 + *
6907 + * Written by Bill Tutt <billtut@microsoft.com>.  Minor tweaks
6908 + * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
6909 + * Return code handling by David Bolen <db3l@fitlinxx.com>.
6910 + */
6911 +
6912 +#include <malloc.h>
6913 +#include <io.h>
6914 +#include <fcntl.h>
6915 +
6916 +/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
6917 +#define POPEN_1 1
6918 +#define POPEN_2 2
6919 +#define POPEN_3 3
6920 +#define POPEN_4 4
6921 +
6922 +static PyObject *_PyPopen(char *, int, int);
6923 +static int _PyPclose(FILE *file);
6924 +
6925 +/*
6926 + * Internal dictionary mapping popen* file pointers to process handles,
6927 + * for use when retrieving the process exit code.  See _PyPclose() below
6928 + * for more information on this dictionary's use.
6929 + */
6930 +static PyObject *_PyPopenProcs = NULL;
6931 +
6932 +
6933 +/* popen that works from a GUI.
6934 + *
6935 + * The result of this function is a pipe (file) connected to the
6936 + * processes stdin or stdout, depending on the requested mode.
6937 + */
6938 +
6939 +static PyObject *
6940 +posix_popen(PyObject *self, PyObject *args)
6941 +{
6942 +       PyObject *f;
6943 +       int tm = 0;
6944 +
6945 +       char *cmdstring;
6946 +       char *mode = "r";
6947 +       int bufsize = -1;
6948 +       if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
6949 +               return NULL;
6950 +
6951 +       if (*mode == 'r')
6952 +               tm = _O_RDONLY;
6953 +       else if (*mode != 'w') {
6954 +               PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
6955 +               return NULL;
6956 +       } else
6957 +               tm = _O_WRONLY;
6958 +
6959 +       if (bufsize != -1) {
6960 +               PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
6961 +               return NULL;
6962 +       }
6963 +
6964 +       if (*(mode+1) == 't')
6965 +               f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
6966 +       else if (*(mode+1) == 'b')
6967 +               f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
6968 +       else
6969 +               f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
6970 +
6971 +       return f;
6972 +}
6973 +
6974 +/* Variation on win32pipe.popen
6975 + *
6976 + * The result of this function is a pipe (file) connected to the
6977 + * process's stdin, and a pipe connected to the process's stdout.
6978 + */
6979 +
6980 +static PyObject *
6981 +win32_popen2(PyObject *self, PyObject  *args)
6982 +{
6983 +       PyObject *f;
6984 +       int tm=0;
6985 +
6986 +       char *cmdstring;
6987 +       char *mode = "t";
6988 +       int bufsize = -1;
6989 +       if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
6990 +               return NULL;
6991 +
6992 +       if (*mode == 't')
6993 +               tm = _O_TEXT;
6994 +       else if (*mode != 'b') {
6995 +               PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
6996 +               return NULL;
6997 +       } else
6998 +               tm = _O_BINARY;
6999 +
7000 +       if (bufsize != -1) {
7001 +               PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
7002 +               return NULL;
7003 +       }
7004 +
7005 +       f = _PyPopen(cmdstring, tm, POPEN_2);
7006 +
7007 +       return f;
7008 +}
7009 +
7010 +/*
7011 + * Variation on <om win32pipe.popen>
7012 + *
7013 + * The result of this function is 3 pipes - the process's stdin,
7014 + * stdout and stderr
7015 + */
7016 +
7017 +static PyObject *
7018 +win32_popen3(PyObject *self, PyObject *args)
7019 +{
7020 +       PyObject *f;
7021 +       int tm = 0;
7022 +
7023 +       char *cmdstring;
7024 +       char *mode = "t";
7025 +       int bufsize = -1;
7026 +       if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
7027 +               return NULL;
7028 +
7029 +       if (*mode == 't')
7030 +               tm = _O_TEXT;
7031 +       else if (*mode != 'b') {
7032 +               PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
7033 +               return NULL;
7034 +       } else
7035 +               tm = _O_BINARY;
7036 +
7037 +       if (bufsize != -1) {
7038 +               PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
7039 +               return NULL;
7040 +       }
7041 +
7042 +       f = _PyPopen(cmdstring, tm, POPEN_3);
7043 +
7044 +       return f;
7045 +}
7046 +
7047 +/*
7048 + * Variation on win32pipe.popen
7049 + *
7050 + * The result of this function is 2 pipes - the processes stdin,
7051 + * and stdout+stderr combined as a single pipe.
7052 + */
7053 +
7054 +static PyObject *
7055 +win32_popen4(PyObject *self, PyObject  *args)
7056 +{
7057 +       PyObject *f;
7058 +       int tm = 0;
7059 +
7060 +       char *cmdstring;
7061 +       char *mode = "t";
7062 +       int bufsize = -1;
7063 +       if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
7064 +               return NULL;
7065 +
7066 +       if (*mode == 't')
7067 +               tm = _O_TEXT;
7068 +       else if (*mode != 'b') {
7069 +               PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
7070 +               return NULL;
7071 +       } else
7072 +               tm = _O_BINARY;
7073 +
7074 +       if (bufsize != -1) {
7075 +               PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
7076 +               return NULL;
7077 +       }
7078 +
7079 +       f = _PyPopen(cmdstring, tm, POPEN_4);
7080 +
7081 +       return f;
7082 +}
7083 +
7084 +static BOOL
7085 +_PyPopenCreateProcess(char *cmdstring,
7086 +                     HANDLE hStdin,
7087 +                     HANDLE hStdout,
7088 +                     HANDLE hStderr,
7089 +                     HANDLE *hProcess)
7090 +{
7091 +       PROCESS_INFORMATION piProcInfo;
7092 +       STARTUPINFO siStartInfo;
7093 +       DWORD dwProcessFlags = 0;  /* no NEW_CONSOLE by default for Ctrl+C handling */
7094 +       char *s1,*s2, *s3 = " /c ";
7095 +       const char *szConsoleSpawn = "w9xpopen.exe";
7096 +       int i;
7097 +       Py_ssize_t x;
7098 +
7099 +       if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
7100 +               char *comshell;
7101 +
7102 +               s1 = (char *)alloca(i);
7103 +               if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
7104 +                       /* x < i, so x fits into an integer */
7105 +                       return (int)x;
7106 +
7107 +               /* Explicitly check if we are using COMMAND.COM.  If we are
7108 +                * then use the w9xpopen hack.
7109 +                */
7110 +               comshell = s1 + x;
7111 +               while (comshell >= s1 && *comshell != '\\')
7112 +                       --comshell;
7113 +               ++comshell;
7114 +
7115 +               if (GetVersion() < 0x80000000 &&
7116 +                   _stricmp(comshell, "command.com") != 0) {
7117 +                       /* NT/2000 and not using command.com. */
7118 +                       x = i + strlen(s3) + strlen(cmdstring) + 1;
7119 +                       s2 = (char *)alloca(x);
7120 +                       ZeroMemory(s2, x);
7121 +                       PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
7122 +               }
7123 +               else {
7124 +                       /*
7125 +                        * Oh gag, we're on Win9x or using COMMAND.COM. Use
7126 +                        * the workaround listed in KB: Q150956
7127 +                        */
7128 +                       char modulepath[_MAX_PATH];
7129 +                       struct stat statinfo;
7130 +                       GetModuleFileName(NULL, modulepath, sizeof(modulepath));
7131 +                       for (x = i = 0; modulepath[i]; i++)
7132 +                               if (modulepath[i] == SEP)
7133 +                                       x = i+1;
7134 +                       modulepath[x] = '\0';
7135 +                       /* Create the full-name to w9xpopen, so we can test it exists */
7136 +                       strncat(modulepath,
7137 +                               szConsoleSpawn,
7138 +                               (sizeof(modulepath)/sizeof(modulepath[0]))
7139 +                                      -strlen(modulepath));
7140 +                       if (stat(modulepath, &statinfo) != 0) {
7141 +                               size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
7142 +                               /* Eeek - file-not-found - possibly an embedding
7143 +                                  situation - see if we can locate it in sys.prefix
7144 +                               */
7145 +                               strncpy(modulepath,
7146 +                                       Py_GetExecPrefix(),
7147 +                                       mplen);
7148 +                               modulepath[mplen-1] = '\0';
7149 +                               if (modulepath[strlen(modulepath)-1] != '\\')
7150 +                                       strcat(modulepath, "\\");
7151 +                               strncat(modulepath,
7152 +                                       szConsoleSpawn,
7153 +                                       mplen-strlen(modulepath));
7154 +                               /* No where else to look - raise an easily identifiable
7155 +                                  error, rather than leaving Windows to report
7156 +                                  "file not found" - as the user is probably blissfully
7157 +                                  unaware this shim EXE is used, and it will confuse them.
7158 +                                  (well, it confused me for a while ;-)
7159 +                               */
7160 +                               if (stat(modulepath, &statinfo) != 0) {
7161 +                                       PyErr_Format(PyExc_RuntimeError,
7162 +                                           "Can not locate '%s' which is needed "
7163 +                                           "for popen to work with your shell "
7164 +                                           "or platform.",
7165 +                                           szConsoleSpawn);
7166 +                                       return FALSE;
7167 +                               }
7168 +                       }
7169 +                       x = i + strlen(s3) + strlen(cmdstring) + 1 +
7170 +                               strlen(modulepath) +
7171 +                               strlen(szConsoleSpawn) + 1;
7172 +
7173 +                       s2 = (char *)alloca(x);
7174 +                       ZeroMemory(s2, x);
7175 +                       /* To maintain correct argument passing semantics,
7176 +                          we pass the command-line as it stands, and allow
7177 +                          quoting to be applied.  w9xpopen.exe will then
7178 +                          use its argv vector, and re-quote the necessary
7179 +                          args for the ultimate child process.
7180 +                       */
7181 +                       PyOS_snprintf(
7182 +                               s2, x,
7183 +                               "\"%s\" %s%s%s",
7184 +                               modulepath,
7185 +                               s1,
7186 +                               s3,
7187 +                               cmdstring);
7188 +                       /* Not passing CREATE_NEW_CONSOLE has been known to
7189 +                          cause random failures on win9x.  Specifically a
7190 +                          dialog:
7191 +                          "Your program accessed mem currently in use at xxx"
7192 +                          and a hopeful warning about the stability of your
7193 +                          system.
7194 +                          Cost is Ctrl+C wont kill children, but anyone
7195 +                          who cares can have a go!
7196 +                       */
7197 +                       dwProcessFlags |= CREATE_NEW_CONSOLE;
7198 +               }
7199 +       }
7200 +
7201 +       /* Could be an else here to try cmd.exe / command.com in the path
7202 +          Now we'll just error out.. */
7203 +       else {
7204 +               PyErr_SetString(PyExc_RuntimeError,
7205 +                       "Cannot locate a COMSPEC environment variable to "
7206 +                       "use as the shell");
7207 +               return FALSE;
7208 +       }
7209 +
7210 +       ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
7211 +       siStartInfo.cb = sizeof(STARTUPINFO);
7212 +       siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
7213 +       siStartInfo.hStdInput = hStdin;
7214 +       siStartInfo.hStdOutput = hStdout;
7215 +       siStartInfo.hStdError = hStderr;
7216 +       siStartInfo.wShowWindow = SW_HIDE;
7217 +
7218 +       if (CreateProcess(NULL,
7219 +                         s2,
7220 +                         NULL,
7221 +                         NULL,
7222 +                         TRUE,
7223 +                         dwProcessFlags,
7224 +                         NULL,
7225 +                         NULL,
7226 +                         &siStartInfo,
7227 +                         &piProcInfo) ) {
7228 +               /* Close the handles now so anyone waiting is woken. */
7229 +               CloseHandle(piProcInfo.hThread);
7230 +
7231 +               /* Return process handle */
7232 +               *hProcess = piProcInfo.hProcess;
7233 +               return TRUE;
7234 +       }
7235 +       win32_error("CreateProcess", s2);
7236 +       return FALSE;
7237 +}
7238 +
7239 +/* The following code is based off of KB: Q190351 */
7240 +
7241 +static PyObject *
7242 +_PyPopen(char *cmdstring, int mode, int n)
7243 +{
7244 +       HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
7245 +               hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
7246 +               hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
7247 +
7248 +       SECURITY_ATTRIBUTES saAttr;
7249 +       BOOL fSuccess;
7250 +       int fd1, fd2, fd3;
7251 +       FILE *f1, *f2, *f3;
7252 +       long file_count;
7253 +       PyObject *f;
7254 +
7255 +       saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
7256 +       saAttr.bInheritHandle = TRUE;
7257 +       saAttr.lpSecurityDescriptor = NULL;
7258 +
7259 +       if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
7260 +               return win32_error("CreatePipe", NULL);
7261 +
7262 +       /* Create new output read handle and the input write handle. Set
7263 +        * the inheritance properties to FALSE. Otherwise, the child inherits
7264 +        * these handles; resulting in non-closeable handles to the pipes
7265 +        * being created. */
7266 +        fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
7267 +                                   GetCurrentProcess(), &hChildStdinWrDup, 0,
7268 +                                   FALSE,
7269 +                                   DUPLICATE_SAME_ACCESS);
7270 +        if (!fSuccess)
7271 +                return win32_error("DuplicateHandle", NULL);
7272 +
7273 +        /* Close the inheritable version of ChildStdin
7274 +       that we're using. */
7275 +        CloseHandle(hChildStdinWr);
7276 +
7277 +        if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
7278 +                return win32_error("CreatePipe", NULL);
7279 +
7280 +        fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
7281 +                                   GetCurrentProcess(), &hChildStdoutRdDup, 0,
7282 +                                   FALSE, DUPLICATE_SAME_ACCESS);
7283 +        if (!fSuccess)
7284 +                return win32_error("DuplicateHandle", NULL);
7285 +
7286 +        /* Close the inheritable version of ChildStdout
7287 +               that we're using. */
7288 +        CloseHandle(hChildStdoutRd);
7289 +
7290 +        if (n != POPEN_4) {
7291 +                if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
7292 +                        return win32_error("CreatePipe", NULL);
7293 +                fSuccess = DuplicateHandle(GetCurrentProcess(),
7294 +                                           hChildStderrRd,
7295 +                                           GetCurrentProcess(),
7296 +                                           &hChildStderrRdDup, 0,
7297 +                                           FALSE, DUPLICATE_SAME_ACCESS);
7298 +                if (!fSuccess)
7299 +                        return win32_error("DuplicateHandle", NULL);
7300 +                /* Close the inheritable version of ChildStdErr that we're using. */
7301 +                CloseHandle(hChildStderrRd);
7302 +        }
7303 +
7304 +        switch (n) {
7305 +        case POPEN_1:
7306 +                switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
7307 +                case _O_WRONLY | _O_TEXT:
7308 +                        /* Case for writing to child Stdin in text mode. */
7309 +                        fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
7310 +                        f1 = _fdopen(fd1, "w");
7311 +                        f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
7312 +                        PyFile_SetBufSize(f, 0);
7313 +                        /* We don't care about these pipes anymore, so close them. */
7314 +                        CloseHandle(hChildStdoutRdDup);
7315 +                        CloseHandle(hChildStderrRdDup);
7316 +                        break;
7317 +
7318 +                case _O_RDONLY | _O_TEXT:
7319 +                        /* Case for reading from child Stdout in text mode. */
7320 +                        fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
7321 +                        f1 = _fdopen(fd1, "r");
7322 +                        f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
7323 +                        PyFile_SetBufSize(f, 0);
7324 +                        /* We don't care about these pipes anymore, so close them. */
7325 +                        CloseHandle(hChildStdinWrDup);
7326 +                        CloseHandle(hChildStderrRdDup);
7327 +                        break;
7328 +
7329 +                case _O_RDONLY | _O_BINARY:
7330 +                        /* Case for readinig from child Stdout in binary mode. */
7331 +                        fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
7332 +                        f1 = _fdopen(fd1, "rb");
7333 +                        f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
7334 +                        PyFile_SetBufSize(f, 0);
7335 +                        /* We don't care about these pipes anymore, so close them. */
7336 +                        CloseHandle(hChildStdinWrDup);
7337 +                        CloseHandle(hChildStderrRdDup);
7338 +                        break;
7339 +
7340 +                case _O_WRONLY | _O_BINARY:
7341 +                        /* Case for writing to child Stdin in binary mode. */
7342 +                        fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
7343 +                        f1 = _fdopen(fd1, "wb");
7344 +                        f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
7345 +                        PyFile_SetBufSize(f, 0);
7346 +                        /* We don't care about these pipes anymore, so close them. */
7347 +                        CloseHandle(hChildStdoutRdDup);
7348 +                        CloseHandle(hChildStderrRdDup);
7349 +                        break;
7350 +                }
7351 +                file_count = 1;
7352 +                break;
7353 +
7354 +        case POPEN_2:
7355 +        case POPEN_4:
7356 +        {
7357 +                char *m1, *m2;
7358 +                PyObject *p1, *p2;
7359 +
7360 +                if (mode & _O_TEXT) {
7361 +                        m1 = "r";
7362 +                        m2 = "w";
7363 +                } else {
7364 +                        m1 = "rb";
7365 +                        m2 = "wb";
7366 +                }
7367 +
7368 +                fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
7369 +                f1 = _fdopen(fd1, m2);
7370 +                fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
7371 +                f2 = _fdopen(fd2, m1);
7372 +                p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
7373 +                PyFile_SetBufSize(p1, 0);
7374 +                p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
7375 +                PyFile_SetBufSize(p2, 0);
7376 +
7377 +                if (n != 4)
7378 +                        CloseHandle(hChildStderrRdDup);
7379 +
7380 +                f = PyTuple_Pack(2,p1,p2);
7381 +                Py_XDECREF(p1);
7382 +                Py_XDECREF(p2);
7383 +                file_count = 2;
7384 +                break;
7385 +        }
7386 +
7387 +        case POPEN_3:
7388 +        {
7389 +                char *m1, *m2;
7390 +                PyObject *p1, *p2, *p3;
7391 +
7392 +                if (mode & _O_TEXT) {
7393 +                        m1 = "r";
7394 +                        m2 = "w";
7395 +                } else {
7396 +                        m1 = "rb";
7397 +                        m2 = "wb";
7398 +                }
7399 +
7400 +                fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
7401 +                f1 = _fdopen(fd1, m2);
7402 +                fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
7403 +                f2 = _fdopen(fd2, m1);
7404 +                fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
7405 +                f3 = _fdopen(fd3, m1);
7406 +                p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
7407 +                p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
7408 +                p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
7409 +                PyFile_SetBufSize(p1, 0);
7410 +                PyFile_SetBufSize(p2, 0);
7411 +                PyFile_SetBufSize(p3, 0);
7412 +                f = PyTuple_Pack(3,p1,p2,p3);
7413 +                Py_XDECREF(p1);
7414 +                Py_XDECREF(p2);
7415 +                Py_XDECREF(p3);
7416 +                file_count = 3;
7417 +                break;
7418 +        }
7419 +        }
7420 +
7421 +        if (n == POPEN_4) {
7422 +                if (!_PyPopenCreateProcess(cmdstring,
7423 +                                           hChildStdinRd,
7424 +                                           hChildStdoutWr,
7425 +                                           hChildStdoutWr,
7426 +                                           &hProcess))
7427 +                        return NULL;
7428 +        }
7429 +        else {
7430 +                if (!_PyPopenCreateProcess(cmdstring,
7431 +                                           hChildStdinRd,
7432 +                                           hChildStdoutWr,
7433 +                                           hChildStderrWr,
7434 +                                           &hProcess))
7435 +                        return NULL;
7436 +        }
7437 +
7438 +        /*
7439 +         * Insert the files we've created into the process dictionary
7440 +         * all referencing the list with the process handle and the
7441 +         * initial number of files (see description below in _PyPclose).
7442 +         * Since if _PyPclose later tried to wait on a process when all
7443 +         * handles weren't closed, it could create a deadlock with the
7444 +         * child, we spend some energy here to try to ensure that we
7445 +         * either insert all file handles into the dictionary or none
7446 +         * at all.  It's a little clumsy with the various popen modes
7447 +         * and variable number of files involved.
7448 +         */
7449 +        if (!_PyPopenProcs) {
7450 +                _PyPopenProcs = PyDict_New();
7451 +        }
7452 +
7453 +        if (_PyPopenProcs) {
7454 +                PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
7455 +                int ins_rc[3];
7456 +
7457 +                fileObj[0] = fileObj[1] = fileObj[2] = NULL;
7458 +                ins_rc[0]  = ins_rc[1]  = ins_rc[2]  = 0;
7459 +
7460 +                procObj = PyList_New(2);
7461 +                hProcessObj = PyLong_FromVoidPtr(hProcess);
7462 +                intObj = PyInt_FromLong(file_count);
7463 +
7464 +                if (procObj && hProcessObj && intObj) {
7465 +                        PyList_SetItem(procObj,0,hProcessObj);
7466 +                        PyList_SetItem(procObj,1,intObj);
7467 +
7468 +                        fileObj[0] = PyLong_FromVoidPtr(f1);
7469 +                        if (fileObj[0]) {
7470 +                           ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
7471 +                                                      fileObj[0],
7472 +                                                      procObj);
7473 +                        }
7474 +                        if (file_count >= 2) {
7475 +                                fileObj[1] = PyLong_FromVoidPtr(f2);
7476 +                                if (fileObj[1]) {
7477 +                                   ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
7478 +                                                              fileObj[1],
7479 +                                                              procObj);
7480 +                                }
7481 +                        }
7482 +                        if (file_count >= 3) {
7483 +                                fileObj[2] = PyLong_FromVoidPtr(f3);
7484 +                                if (fileObj[2]) {
7485 +                                   ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
7486 +                                                              fileObj[2],
7487 +                                                              procObj);
7488 +                                }
7489 +                        }
7490 +
7491 +                        if (ins_rc[0] < 0 || !fileObj[0] ||
7492 +                            ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
7493 +                            ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
7494 +                                /* Something failed - remove any dictionary
7495 +                                 * entries that did make it.
7496 +                                 */
7497 +                                if (!ins_rc[0] && fileObj[0]) {
7498 +                                        PyDict_DelItem(_PyPopenProcs,
7499 +                                                       fileObj[0]);
7500 +                                }
7501 +                                if (!ins_rc[1] && fileObj[1]) {
7502 +                                        PyDict_DelItem(_PyPopenProcs,
7503 +                                                       fileObj[1]);
7504 +                                }
7505 +                                if (!ins_rc[2] && fileObj[2]) {
7506 +                                        PyDict_DelItem(_PyPopenProcs,
7507 +                                                       fileObj[2]);
7508 +                                }
7509 +                        }
7510 +                }
7511 +
7512 +                /*
7513 +                 * Clean up our localized references for the dictionary keys
7514 +                 * and value since PyDict_SetItem will Py_INCREF any copies
7515 +                 * that got placed in the dictionary.
7516 +                 */
7517 +                Py_XDECREF(procObj);
7518 +                Py_XDECREF(fileObj[0]);
7519 +                Py_XDECREF(fileObj[1]);
7520 +                Py_XDECREF(fileObj[2]);
7521 +        }
7522 +
7523 +        /* Child is launched. Close the parents copy of those pipe
7524 +         * handles that only the child should have open.  You need to
7525 +         * make sure that no handles to the write end of the output pipe
7526 +         * are maintained in this process or else the pipe will not close
7527 +         * when the child process exits and the ReadFile will hang. */
7528 +
7529 +        if (!CloseHandle(hChildStdinRd))
7530 +                return win32_error("CloseHandle", NULL);
7531 +
7532 +        if (!CloseHandle(hChildStdoutWr))
7533 +                return win32_error("CloseHandle", NULL);
7534 +
7535 +        if ((n != 4) && (!CloseHandle(hChildStderrWr)))
7536 +                return win32_error("CloseHandle", NULL);
7537 +
7538 +        return f;
7539 +}
7540 +
7541 +/*
7542 + * Wrapper for fclose() to use for popen* files, so we can retrieve the
7543 + * exit code for the child process and return as a result of the close.
7544 + *
7545 + * This function uses the _PyPopenProcs dictionary in order to map the
7546 + * input file pointer to information about the process that was
7547 + * originally created by the popen* call that created the file pointer.
7548 + * The dictionary uses the file pointer as a key (with one entry
7549 + * inserted for each file returned by the original popen* call) and a
7550 + * single list object as the value for all files from a single call.
7551 + * The list object contains the Win32 process handle at [0], and a file
7552 + * count at [1], which is initialized to the total number of file
7553 + * handles using that list.
7554 + *
7555 + * This function closes whichever handle it is passed, and decrements
7556 + * the file count in the dictionary for the process handle pointed to
7557 + * by this file.  On the last close (when the file count reaches zero),
7558 + * this function will wait for the child process and then return its
7559 + * exit code as the result of the close() operation.  This permits the
7560 + * files to be closed in any order - it is always the close() of the
7561 + * final handle that will return the exit code.
7562 + *
7563 + * NOTE: This function is currently called with the GIL released.
7564 + * hence we use the GILState API to manage our state.
7565 + */
7566 +
7567 +static int _PyPclose(FILE *file)
7568 +{
7569 +       int result;
7570 +       DWORD exit_code;
7571 +       HANDLE hProcess;
7572 +       PyObject *procObj, *hProcessObj, *intObj, *fileObj;
7573 +       long file_count;
7574 +#ifdef WITH_THREAD
7575 +       PyGILState_STATE state;
7576 +#endif
7577 +
7578 +       /* Close the file handle first, to ensure it can't block the
7579 +        * child from exiting if it's the last handle.
7580 +        */
7581 +       result = fclose(file);
7582 +#ifdef WITH_THREAD
7583 +       state = PyGILState_Ensure();
7584 +#endif
7585 +       if (_PyPopenProcs) {
7586 +               if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
7587 +                   (procObj = PyDict_GetItem(_PyPopenProcs,
7588 +                                             fileObj)) != NULL &&
7589 +                   (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
7590 +                   (intObj = PyList_GetItem(procObj,1)) != NULL) {
7591 +
7592 +                       hProcess = PyLong_AsVoidPtr(hProcessObj);
7593 +                       file_count = PyInt_AsLong(intObj);
7594 +
7595 +                       if (file_count > 1) {
7596 +                               /* Still other files referencing process */
7597 +                               file_count--;
7598 +                               PyList_SetItem(procObj,1,
7599 +                                              PyInt_FromLong(file_count));
7600 +                       } else {
7601 +                               /* Last file for this process */
7602 +                               if (result != EOF &&
7603 +                                   WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
7604 +                                   GetExitCodeProcess(hProcess, &exit_code)) {
7605 +                                       /* Possible truncation here in 16-bit environments, but
7606 +                                        * real exit codes are just the lower byte in any event.
7607 +                                        */
7608 +                                       result = exit_code;
7609 +                               } else {
7610 +                                       /* Indicate failure - this will cause the file object
7611 +                                        * to raise an I/O error and translate the last Win32
7612 +                                        * error code from errno.  We do have a problem with
7613 +                                        * last errors that overlap the normal errno table,
7614 +                                        * but that's a consistent problem with the file object.
7615 +                                        */
7616 +                                       if (result != EOF) {
7617 +                                               /* If the error wasn't from the fclose(), then
7618 +                                                * set errno for the file object error handling.
7619 +                                                */
7620 +                                               errno = GetLastError();
7621 +                                       }
7622 +                                       result = -1;
7623 +                               }
7624 +
7625 +                               /* Free up the native handle at this point */
7626 +                               CloseHandle(hProcess);
7627 +                       }
7628 +
7629 +                       /* Remove this file pointer from dictionary */
7630 +                       PyDict_DelItem(_PyPopenProcs, fileObj);
7631 +
7632 +                       if (PyDict_Size(_PyPopenProcs) == 0) {
7633 +                               Py_DECREF(_PyPopenProcs);
7634 +                               _PyPopenProcs = NULL;
7635 +                       }
7636 +
7637 +               } /* if object retrieval ok */
7638 +
7639 +               Py_XDECREF(fileObj);
7640 +       } /* if _PyPopenProcs */
7641 +
7642 +#ifdef WITH_THREAD
7643 +       PyGILState_Release(state);
7644 +#endif
7645 +       return result;
7646 +}
7647 +
7648 +#else /* which OS? */
7649 +static PyObject *
7650 +posix_popen(PyObject *self, PyObject *args)
7651 +{
7652 +       char *name;
7653 +       char *mode = "r";
7654 +       int bufsize = -1;
7655 +       FILE *fp;
7656 +       PyObject *f;
7657 +       if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
7658 +               return NULL;
7659 +       /* Strip mode of binary or text modifiers */
7660 +       if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
7661 +               mode = "r";
7662 +       else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
7663 +               mode = "w";
7664 +       Py_BEGIN_ALLOW_THREADS
7665 +       fp = popen(name, mode);
7666 +       Py_END_ALLOW_THREADS
7667 +       if (fp == NULL)
7668 +               return posix_error();
7669 +       f = PyFile_FromFile(fp, name, mode, pclose);
7670 +       if (f != NULL)
7671 +               PyFile_SetBufSize(f, bufsize);
7672 +       return f;
7673 +}
7674 +
7675 +#endif /* PYOS_??? */
7676 +#endif /* HAVE_POPEN */
7677 +
7678 +
7679 +#ifdef HAVE_SETUID
7680 +PyDoc_STRVAR(posix_setuid__doc__,
7681 +"setuid(uid)\n\n\
7682 +Set the current process's user id.");
7683 +
7684 +static PyObject *
7685 +posix_setuid(PyObject *self, PyObject *args)
7686 +{
7687 +       int uid;
7688 +       if (!PyArg_ParseTuple(args, "i:setuid", &uid))
7689 +               return NULL;
7690 +       if (setuid(uid) < 0)
7691 +               return posix_error();
7692 +       Py_INCREF(Py_None);
7693 +       return Py_None;
7694 +}
7695 +#endif /* HAVE_SETUID */
7696 +
7697 +
7698 +#ifdef HAVE_SETEUID
7699 +PyDoc_STRVAR(posix_seteuid__doc__,
7700 +"seteuid(uid)\n\n\
7701 +Set the current process's effective user id.");
7702 +
7703 +static PyObject *
7704 +posix_seteuid (PyObject *self, PyObject *args)
7705 +{
7706 +       int euid;
7707 +       if (!PyArg_ParseTuple(args, "i", &euid)) {
7708 +               return NULL;
7709 +       } else if (seteuid(euid) < 0) {
7710 +               return posix_error();
7711 +       } else {
7712 +               Py_INCREF(Py_None);
7713 +               return Py_None;
7714 +       }
7715 +}
7716 +#endif /* HAVE_SETEUID */
7717 +
7718 +#ifdef HAVE_SETEGID
7719 +PyDoc_STRVAR(posix_setegid__doc__,
7720 +"setegid(gid)\n\n\
7721 +Set the current process's effective group id.");
7722 +
7723 +static PyObject *
7724 +posix_setegid (PyObject *self, PyObject *args)
7725 +{
7726 +       int egid;
7727 +       if (!PyArg_ParseTuple(args, "i", &egid)) {
7728 +               return NULL;
7729 +       } else if (setegid(egid) < 0) {
7730 +               return posix_error();
7731 +       } else {
7732 +               Py_INCREF(Py_None);
7733 +               return Py_None;
7734 +       }
7735 +}
7736 +#endif /* HAVE_SETEGID */
7737 +
7738 +#ifdef HAVE_SETREUID
7739 +PyDoc_STRVAR(posix_setreuid__doc__,
7740 +"setreuid(ruid, euid)\n\n\
7741 +Set the current process's real and effective user ids.");
7742 +
7743 +static PyObject *
7744 +posix_setreuid (PyObject *self, PyObject *args)
7745 +{
7746 +       int ruid, euid;
7747 +       if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
7748 +               return NULL;
7749 +       } else if (setreuid(ruid, euid) < 0) {
7750 +               return posix_error();
7751 +       } else {
7752 +               Py_INCREF(Py_None);
7753 +               return Py_None;
7754 +       }
7755 +}
7756 +#endif /* HAVE_SETREUID */
7757 +
7758 +#ifdef HAVE_SETREGID
7759 +PyDoc_STRVAR(posix_setregid__doc__,
7760 +"setregid(rgid, egid)\n\n\
7761 +Set the current process's real and effective group ids.");
7762 +
7763 +static PyObject *
7764 +posix_setregid (PyObject *self, PyObject *args)
7765 +{
7766 +       int rgid, egid;
7767 +       if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
7768 +               return NULL;
7769 +       } else if (setregid(rgid, egid) < 0) {
7770 +               return posix_error();
7771 +       } else {
7772 +               Py_INCREF(Py_None);
7773 +               return Py_None;
7774 +       }
7775 +}
7776 +#endif /* HAVE_SETREGID */
7777 +
7778 +#ifdef HAVE_SETGID
7779 +PyDoc_STRVAR(posix_setgid__doc__,
7780 +"setgid(gid)\n\n\
7781 +Set the current process's group id.");
7782 +
7783 +static PyObject *
7784 +posix_setgid(PyObject *self, PyObject *args)
7785 +{
7786 +       int gid;
7787 +       if (!PyArg_ParseTuple(args, "i:setgid", &gid))
7788 +               return NULL;
7789 +       if (setgid(gid) < 0)
7790 +               return posix_error();
7791 +       Py_INCREF(Py_None);
7792 +       return Py_None;
7793 +}
7794 +#endif /* HAVE_SETGID */
7795 +
7796 +#ifdef HAVE_SETGROUPS
7797 +PyDoc_STRVAR(posix_setgroups__doc__,
7798 +"setgroups(list)\n\n\
7799 +Set the groups of the current process to list.");
7800 +
7801 +static PyObject *
7802 +posix_setgroups(PyObject *self, PyObject *groups)
7803 +{
7804 +       int i, len;
7805 +        gid_t grouplist[MAX_GROUPS];
7806 +
7807 +       if (!PySequence_Check(groups)) {
7808 +               PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7809 +               return NULL;
7810 +       }
7811 +       len = PySequence_Size(groups);
7812 +       if (len > MAX_GROUPS) {
7813 +               PyErr_SetString(PyExc_ValueError, "too many groups");
7814 +               return NULL;
7815 +       }
7816 +       for(i = 0; i < len; i++) {
7817 +               PyObject *elem;
7818 +               elem = PySequence_GetItem(groups, i);
7819 +               if (!elem)
7820 +                       return NULL;
7821 +               if (!PyInt_Check(elem)) {
7822 +                       if (!PyLong_Check(elem)) {
7823 +                               PyErr_SetString(PyExc_TypeError,
7824 +                                               "groups must be integers");
7825 +                               Py_DECREF(elem);
7826 +                               return NULL;
7827 +                       } else {
7828 +                               unsigned long x = PyLong_AsUnsignedLong(elem);
7829 +                               if (PyErr_Occurred()) {
7830 +                                       PyErr_SetString(PyExc_TypeError, 
7831 +                                                       "group id too big");
7832 +                                       Py_DECREF(elem);
7833 +                                       return NULL;
7834 +                               }
7835 +                               grouplist[i] = x;
7836 +                               /* read back the value to see if it fitted in gid_t */
7837 +                               if (grouplist[i] != x) {
7838 +                                       PyErr_SetString(PyExc_TypeError,
7839 +                                                       "group id too big");
7840 +                                       Py_DECREF(elem);
7841 +                                       return NULL;
7842 +                               }
7843 +                       }
7844 +               } else {
7845 +                       long x  = PyInt_AsLong(elem);
7846 +                       grouplist[i] = x;
7847 +                       if (grouplist[i] != x) {
7848 +                               PyErr_SetString(PyExc_TypeError,
7849 +                                               "group id too big");
7850 +                               Py_DECREF(elem);
7851 +                               return NULL;
7852 +                       }
7853 +               }
7854 +               Py_DECREF(elem);
7855 +       }
7856 +
7857 +       if (setgroups(len, grouplist) < 0)
7858 +               return posix_error();
7859 +       Py_INCREF(Py_None);
7860 +       return Py_None;
7861 +}
7862 +#endif /* HAVE_SETGROUPS */
7863 +
7864 +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7865 +static PyObject *
7866 +wait_helper(int pid, int status, struct rusage *ru)
7867 +{
7868 +       PyObject *result;
7869 +       static PyObject *struct_rusage;
7870 +
7871 +       if (pid == -1)
7872 +               return posix_error();
7873 +
7874 +       if (struct_rusage == NULL) {
7875 +               PyObject *m = PyImport_ImportModule("resource");
7876 +               if (m == NULL)
7877 +                       return NULL;
7878 +               struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
7879 +               Py_DECREF(m);
7880 +               if (struct_rusage == NULL)
7881 +                       return NULL;
7882 +       }
7883 +
7884 +       /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7885 +       result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7886 +       if (!result)
7887 +               return NULL;
7888 +
7889 +#ifndef doubletime
7890 +#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7891 +#endif
7892 +
7893 +       PyStructSequence_SET_ITEM(result, 0,
7894 +                       PyFloat_FromDouble(doubletime(ru->ru_utime)));
7895 +       PyStructSequence_SET_ITEM(result, 1,
7896 +                       PyFloat_FromDouble(doubletime(ru->ru_stime)));
7897 +#define SET_INT(result, index, value)\
7898 +               PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
7899 +       SET_INT(result, 2, ru->ru_maxrss);
7900 +       SET_INT(result, 3, ru->ru_ixrss);
7901 +       SET_INT(result, 4, ru->ru_idrss);
7902 +       SET_INT(result, 5, ru->ru_isrss);
7903 +       SET_INT(result, 6, ru->ru_minflt);
7904 +       SET_INT(result, 7, ru->ru_majflt);
7905 +       SET_INT(result, 8, ru->ru_nswap);
7906 +       SET_INT(result, 9, ru->ru_inblock);
7907 +       SET_INT(result, 10, ru->ru_oublock);
7908 +       SET_INT(result, 11, ru->ru_msgsnd);
7909 +       SET_INT(result, 12, ru->ru_msgrcv);
7910 +       SET_INT(result, 13, ru->ru_nsignals);
7911 +       SET_INT(result, 14, ru->ru_nvcsw);
7912 +       SET_INT(result, 15, ru->ru_nivcsw);
7913 +#undef SET_INT
7914 +
7915 +       if (PyErr_Occurred()) {
7916 +               Py_DECREF(result);
7917 +               return NULL;
7918 +       }
7919 +
7920 +       return Py_BuildValue("iiN", pid, status, result);
7921 +}
7922 +#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7923 +
7924 +#ifdef HAVE_WAIT3
7925 +PyDoc_STRVAR(posix_wait3__doc__,
7926 +"wait3(options) -> (pid, status, rusage)\n\n\
7927 +Wait for completion of a child process.");
7928 +
7929 +static PyObject *
7930 +posix_wait3(PyObject *self, PyObject *args)
7931 +{
7932 +       int pid, options;
7933 +       struct rusage ru;
7934 +       WAIT_TYPE status;
7935 +       WAIT_STATUS_INT(status) = 0;
7936 +
7937 +       if (!PyArg_ParseTuple(args, "i:wait3", &options))
7938 +               return NULL;
7939 +
7940 +       Py_BEGIN_ALLOW_THREADS
7941 +       pid = wait3(&status, options, &ru);
7942 +       Py_END_ALLOW_THREADS
7943 +
7944 +       return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
7945 +}
7946 +#endif /* HAVE_WAIT3 */
7947 +
7948 +#ifdef HAVE_WAIT4
7949 +PyDoc_STRVAR(posix_wait4__doc__,
7950 +"wait4(pid, options) -> (pid, status, rusage)\n\n\
7951 +Wait for completion of a given child process.");
7952 +
7953 +static PyObject *
7954 +posix_wait4(PyObject *self, PyObject *args)
7955 +{
7956 +       int pid, options;
7957 +       struct rusage ru;
7958 +       WAIT_TYPE status;
7959 +       WAIT_STATUS_INT(status) = 0;
7960 +
7961 +       if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
7962 +               return NULL;
7963 +
7964 +       Py_BEGIN_ALLOW_THREADS
7965 +       pid = wait4(pid, &status, options, &ru);
7966 +       Py_END_ALLOW_THREADS
7967 +
7968 +       return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
7969 +}
7970 +#endif /* HAVE_WAIT4 */
7971 +
7972 +#ifdef HAVE_WAITPID
7973 +PyDoc_STRVAR(posix_waitpid__doc__,
7974 +"waitpid(pid, options) -> (pid, status)\n\n\
7975 +Wait for completion of a given child process.");
7976 +
7977 +static PyObject *
7978 +posix_waitpid(PyObject *self, PyObject *args)
7979 +{
7980 +       int pid, options;
7981 +       WAIT_TYPE status;
7982 +       WAIT_STATUS_INT(status) = 0;
7983 +
7984 +       if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
7985 +               return NULL;
7986 +       Py_BEGIN_ALLOW_THREADS
7987 +       pid = waitpid(pid, &status, options);
7988 +       Py_END_ALLOW_THREADS
7989 +       if (pid == -1)
7990 +               return posix_error();
7991 +
7992 +       return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
7993 +}
7994 +
7995 +#elif defined(HAVE_CWAIT)
7996 +
7997 +/* MS C has a variant of waitpid() that's usable for most purposes. */
7998 +PyDoc_STRVAR(posix_waitpid__doc__,
7999 +"waitpid(pid, options) -> (pid, status << 8)\n\n"
8000 +"Wait for completion of a given process.  options is ignored on Windows.");
8001 +
8002 +static PyObject *
8003 +posix_waitpid(PyObject *self, PyObject *args)
8004 +{
8005 +       Py_intptr_t pid;
8006 +       int status, options;
8007 +
8008 +       if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
8009 +               return NULL;
8010 +       Py_BEGIN_ALLOW_THREADS
8011 +       pid = _cwait(&status, pid, options);
8012 +       Py_END_ALLOW_THREADS
8013 +       if (pid == -1)
8014 +               return posix_error();
8015 +
8016 +       /* shift the status left a byte so this is more like the POSIX waitpid */
8017 +       return Py_BuildValue("ii", pid, status << 8);
8018 +}
8019 +#endif /* HAVE_WAITPID || HAVE_CWAIT */
8020 +
8021 +#ifdef HAVE_WAIT
8022 +PyDoc_STRVAR(posix_wait__doc__,
8023 +"wait() -> (pid, status)\n\n\
8024 +Wait for completion of a child process.");
8025 +
8026 +static PyObject *
8027 +posix_wait(PyObject *self, PyObject *noargs)
8028 +{
8029 +       int pid;
8030 +       WAIT_TYPE status;
8031 +       WAIT_STATUS_INT(status) = 0;
8032 +
8033 +       Py_BEGIN_ALLOW_THREADS
8034 +       pid = wait(&status);
8035 +       Py_END_ALLOW_THREADS
8036 +       if (pid == -1)
8037 +               return posix_error();
8038 +
8039 +       return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
8040 +}
8041 +#endif
8042 +
8043 +
8044 +PyDoc_STRVAR(posix_lstat__doc__,
8045 +"lstat(path) -> stat result\n\n\
8046 +Like stat(path), but do not follow symbolic links.");
8047 +
8048 +static PyObject *
8049 +posix_lstat(PyObject *self, PyObject *args)
8050 +{
8051 +#ifdef HAVE_LSTAT
8052 +       return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
8053 +#else /* !HAVE_LSTAT */
8054 +#ifdef MS_WINDOWS
8055 +       return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
8056 +#else
8057 +       return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
8058 +#endif
8059 +#endif /* !HAVE_LSTAT */
8060 +}
8061 +
8062 +
8063 +#ifdef HAVE_READLINK
8064 +PyDoc_STRVAR(posix_readlink__doc__,
8065 +"readlink(path) -> path\n\n\
8066 +Return a string representing the path to which the symbolic link points.");
8067 +
8068 +static PyObject *
8069 +posix_readlink(PyObject *self, PyObject *args)
8070 +{
8071 +       char buf[MAXPATHLEN];
8072 +       char *path;
8073 +       int n;
8074 +       if (!PyArg_ParseTuple(args, "s:readlink", &path))
8075 +               return NULL;
8076 +       Py_BEGIN_ALLOW_THREADS
8077 +       n = readlink(path, buf, (int) sizeof buf);
8078 +       Py_END_ALLOW_THREADS
8079 +       if (n < 0)
8080 +               return posix_error_with_filename(path);
8081 +       return PyString_FromStringAndSize(buf, n);
8082 +}
8083 +#endif /* HAVE_READLINK */
8084 +
8085 +
8086 +#ifdef HAVE_SYMLINK
8087 +PyDoc_STRVAR(posix_symlink__doc__,
8088 +"symlink(src, dst)\n\n\
8089 +Create a symbolic link pointing to src named dst.");
8090 +
8091 +static PyObject *
8092 +posix_symlink(PyObject *self, PyObject *args)
8093 +{
8094 +       return posix_2str(args, "etet:symlink", symlink);
8095 +}
8096 +#endif /* HAVE_SYMLINK */
8097 +
8098 +
8099 +#ifdef HAVE_TIMES
8100 +#ifndef HZ
8101 +#define HZ 60 /* Universal constant :-) */
8102 +#endif /* HZ */
8103 +
8104 +#if defined(PYCC_VACPP) && defined(PYOS_OS2)
8105 +static long
8106 +system_uptime(void)
8107 +{
8108 +    ULONG     value = 0;
8109 +
8110 +    Py_BEGIN_ALLOW_THREADS
8111 +    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
8112 +    Py_END_ALLOW_THREADS
8113 +
8114 +    return value;
8115 +}
8116 +
8117 +static PyObject *
8118 +posix_times(PyObject *self, PyObject *noargs)
8119 +{
8120 +    /* Currently Only Uptime is Provided -- Others Later */
8121 +       return Py_BuildValue("ddddd",
8122 +                            (double)0 /* t.tms_utime / HZ */,
8123 +                            (double)0 /* t.tms_stime / HZ */,
8124 +                            (double)0 /* t.tms_cutime / HZ */,
8125 +                            (double)0 /* t.tms_cstime / HZ */,
8126 +                            (double)system_uptime() / 1000);
8127 +}
8128 +#else /* not OS2 */
8129 +static PyObject *
8130 +posix_times(PyObject *self, PyObject *noargs)
8131 +{
8132 +       struct tms t;
8133 +       clock_t c;
8134 +       errno = 0;
8135 +       c = times(&t);
8136 +       if (c == (clock_t) -1)
8137 +               return posix_error();
8138 +       return Py_BuildValue("ddddd",
8139 +                            (double)t.tms_utime / HZ,
8140 +                            (double)t.tms_stime / HZ,
8141 +                            (double)t.tms_cutime / HZ,
8142 +                            (double)t.tms_cstime / HZ,
8143 +                            (double)c / HZ);
8144 +}
8145 +#endif /* not OS2 */
8146 +#endif /* HAVE_TIMES */
8147 +
8148 +
8149 +#ifdef MS_WINDOWS
8150 +#define HAVE_TIMES     /* so the method table will pick it up */
8151 +static PyObject *
8152 +posix_times(PyObject *self, PyObject *noargs)
8153 +{
8154 +       FILETIME create, exit, kernel, user;
8155 +       HANDLE hProc;
8156 +       hProc = GetCurrentProcess();
8157 +       GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8158 +       /* The fields of a FILETIME structure are the hi and lo part
8159 +          of a 64-bit value expressed in 100 nanosecond units.
8160 +          1e7 is one second in such units; 1e-7 the inverse.
8161 +          429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8162 +       */
8163 +       return Py_BuildValue(
8164 +               "ddddd",
8165 +               (double)(kernel.dwHighDateTime*429.4967296 +
8166 +                        kernel.dwLowDateTime*1e-7),
8167 +               (double)(user.dwHighDateTime*429.4967296 +
8168 +                        user.dwLowDateTime*1e-7),
8169 +               (double)0,
8170 +               (double)0,
8171 +               (double)0);
8172 +}
8173 +#endif /* MS_WINDOWS */
8174 +
8175 +#ifdef HAVE_TIMES
8176 +PyDoc_STRVAR(posix_times__doc__,
8177 +"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
8178 +Return a tuple of floating point numbers indicating process times.");
8179 +#endif
8180 +
8181 +
8182 +#ifdef HAVE_GETSID
8183 +PyDoc_STRVAR(posix_getsid__doc__,
8184 +"getsid(pid) -> sid\n\n\
8185 +Call the system call getsid().");
8186 +
8187 +static PyObject *
8188 +posix_getsid(PyObject *self, PyObject *args)
8189 +{
8190 +       int pid, sid;
8191 +       if (!PyArg_ParseTuple(args, "i:getsid", &pid))
8192 +               return NULL;
8193 +       sid = getsid(pid);
8194 +       if (sid < 0)
8195 +               return posix_error();
8196 +       return PyInt_FromLong((long)sid);
8197 +}
8198 +#endif /* HAVE_GETSID */
8199 +
8200 +
8201 +#ifdef HAVE_SETSID
8202 +PyDoc_STRVAR(posix_setsid__doc__,
8203 +"setsid()\n\n\
8204 +Call the system call setsid().");
8205 +
8206 +static PyObject *
8207 +posix_setsid(PyObject *self, PyObject *noargs)
8208 +{
8209 +       if (setsid() < 0)
8210 +               return posix_error();
8211 +       Py_INCREF(Py_None);
8212 +       return Py_None;
8213 +}
8214 +#endif /* HAVE_SETSID */
8215 +
8216 +#ifdef HAVE_SETPGID
8217 +PyDoc_STRVAR(posix_setpgid__doc__,
8218 +"setpgid(pid, pgrp)\n\n\
8219 +Call the system call setpgid().");
8220 +
8221 +static PyObject *
8222 +posix_setpgid(PyObject *self, PyObject *args)
8223 +{
8224 +       int pid, pgrp;
8225 +       if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
8226 +               return NULL;
8227 +       if (setpgid(pid, pgrp) < 0)
8228 +               return posix_error();
8229 +       Py_INCREF(Py_None);
8230 +       return Py_None;
8231 +}
8232 +#endif /* HAVE_SETPGID */
8233 +
8234 +
8235 +#ifdef HAVE_TCGETPGRP
8236 +PyDoc_STRVAR(posix_tcgetpgrp__doc__,
8237 +"tcgetpgrp(fd) -> pgid\n\n\
8238 +Return the process group associated with the terminal given by a fd.");
8239 +
8240 +static PyObject *
8241 +posix_tcgetpgrp(PyObject *self, PyObject *args)
8242 +{
8243 +       int fd, pgid;
8244 +       if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
8245 +               return NULL;
8246 +       pgid = tcgetpgrp(fd);
8247 +       if (pgid < 0)
8248 +               return posix_error();
8249 +       return PyInt_FromLong((long)pgid);
8250 +}
8251 +#endif /* HAVE_TCGETPGRP */
8252 +
8253 +
8254 +#ifdef HAVE_TCSETPGRP
8255 +PyDoc_STRVAR(posix_tcsetpgrp__doc__,
8256 +"tcsetpgrp(fd, pgid)\n\n\
8257 +Set the process group associated with the terminal given by a fd.");
8258 +
8259 +static PyObject *
8260 +posix_tcsetpgrp(PyObject *self, PyObject *args)
8261 +{
8262 +       int fd, pgid;
8263 +       if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
8264 +               return NULL;
8265 +       if (tcsetpgrp(fd, pgid) < 0)
8266 +               return posix_error();
8267 +       Py_INCREF(Py_None);
8268 +       return Py_None;
8269 +}
8270 +#endif /* HAVE_TCSETPGRP */
8271 +
8272 +/* Functions acting on file descriptors */
8273 +
8274 +PyDoc_STRVAR(posix_open__doc__,
8275 +"open(filename, flag [, mode=0777]) -> fd\n\n\
8276 +Open a file (for low level IO).");
8277 +
8278 +static PyObject *
8279 +posix_open(PyObject *self, PyObject *args)
8280 +{
8281 +       char *file = NULL;
8282 +       int flag;
8283 +       int mode = 0777;
8284 +       int fd;
8285 +
8286 +#ifdef MS_WINDOWS
8287 +       if (unicode_file_names()) {
8288 +               PyUnicodeObject *po;
8289 +               if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
8290 +                       Py_BEGIN_ALLOW_THREADS
8291 +                       /* PyUnicode_AS_UNICODE OK without thread
8292 +                          lock as it is a simple dereference. */
8293 +                       fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
8294 +                       Py_END_ALLOW_THREADS
8295 +                       if (fd < 0)
8296 +                               return posix_error();
8297 +                       return PyInt_FromLong((long)fd);
8298 +               }
8299 +               /* Drop the argument parsing error as narrow strings
8300 +                  are also valid. */
8301 +               PyErr_Clear();
8302 +       }
8303 +#endif
8304 +
8305 +       if (!PyArg_ParseTuple(args, "eti|i",
8306 +                             Py_FileSystemDefaultEncoding, &file,
8307 +                             &flag, &mode))
8308 +               return NULL;
8309 +
8310 +       Py_BEGIN_ALLOW_THREADS
8311 +       fd = open(file, flag, mode);
8312 +       Py_END_ALLOW_THREADS
8313 +       if (fd < 0)
8314 +               return posix_error_with_allocated_filename(file);
8315 +       PyMem_Free(file);
8316 +       return PyInt_FromLong((long)fd);
8317 +}
8318 +
8319 +
8320 +PyDoc_STRVAR(posix_close__doc__,
8321 +"close(fd)\n\n\
8322 +Close a file descriptor (for low level IO).");
8323 +
8324 +static PyObject *
8325 +posix_close(PyObject *self, PyObject *args)
8326 +{
8327 +       int fd, res;
8328 +       if (!PyArg_ParseTuple(args, "i:close", &fd))
8329 +               return NULL;
8330 +       Py_BEGIN_ALLOW_THREADS
8331 +       res = close(fd);
8332 +       Py_END_ALLOW_THREADS
8333 +       if (res < 0)
8334 +               return posix_error();
8335 +       Py_INCREF(Py_None);
8336 +       return Py_None;
8337 +}
8338 +
8339 +
8340 +PyDoc_STRVAR(posix_dup__doc__,
8341 +"dup(fd) -> fd2\n\n\
8342 +Return a duplicate of a file descriptor.");
8343 +
8344 +static PyObject *
8345 +posix_dup(PyObject *self, PyObject *args)
8346 +{
8347 +       int fd;
8348 +       if (!PyArg_ParseTuple(args, "i:dup", &fd))
8349 +               return NULL;
8350 +       Py_BEGIN_ALLOW_THREADS
8351 +       fd = dup(fd);
8352 +       Py_END_ALLOW_THREADS
8353 +       if (fd < 0)
8354 +               return posix_error();
8355 +       return PyInt_FromLong((long)fd);
8356 +}
8357 +
8358 +
8359 +PyDoc_STRVAR(posix_dup2__doc__,
8360 +"dup2(old_fd, new_fd)\n\n\
8361 +Duplicate file descriptor.");
8362 +
8363 +static PyObject *
8364 +posix_dup2(PyObject *self, PyObject *args)
8365 +{
8366 +       int fd, fd2, res;
8367 +       if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
8368 +               return NULL;
8369 +       Py_BEGIN_ALLOW_THREADS
8370 +       res = dup2(fd, fd2);
8371 +       Py_END_ALLOW_THREADS
8372 +       if (res < 0)
8373 +               return posix_error();
8374 +       Py_INCREF(Py_None);
8375 +       return Py_None;
8376 +}
8377 +
8378 +
8379 +PyDoc_STRVAR(posix_lseek__doc__,
8380 +"lseek(fd, pos, how) -> newpos\n\n\
8381 +Set the current position of a file descriptor.");
8382 +
8383 +static PyObject *
8384 +posix_lseek(PyObject *self, PyObject *args)
8385 +{
8386 +       int fd, how;
8387 +#if defined(MS_WIN64) || defined(MS_WINDOWS)
8388 +       PY_LONG_LONG pos, res;
8389 +#else
8390 +       off_t pos, res;
8391 +#endif
8392 +       PyObject *posobj;
8393 +       if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
8394 +               return NULL;
8395 +#ifdef SEEK_SET
8396 +       /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8397 +       switch (how) {
8398 +       case 0: how = SEEK_SET; break;
8399 +       case 1: how = SEEK_CUR; break;
8400 +       case 2: how = SEEK_END; break;
8401 +       }
8402 +#endif /* SEEK_END */
8403 +
8404 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8405 +       pos = PyInt_AsLong(posobj);
8406 +#else
8407 +       pos = PyLong_Check(posobj) ?
8408 +               PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
8409 +#endif
8410 +       if (PyErr_Occurred())
8411 +               return NULL;
8412 +
8413 +       Py_BEGIN_ALLOW_THREADS
8414 +#if defined(MS_WIN64) || defined(MS_WINDOWS)
8415 +       res = _lseeki64(fd, pos, how);
8416 +#else
8417 +       res = lseek(fd, pos, how);
8418 +#endif
8419 +       Py_END_ALLOW_THREADS
8420 +       if (res < 0)
8421 +               return posix_error();
8422 +
8423 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8424 +       return PyInt_FromLong(res);
8425 +#else
8426 +       return PyLong_FromLongLong(res);
8427 +#endif
8428 +}
8429 +
8430 +
8431 +PyDoc_STRVAR(posix_read__doc__,
8432 +"read(fd, buffersize) -> string\n\n\
8433 +Read a file descriptor.");
8434 +
8435 +static PyObject *
8436 +posix_read(PyObject *self, PyObject *args)
8437 +{
8438 +       int fd, size, n;
8439 +       PyObject *buffer;
8440 +       if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8441 +               return NULL;
8442 +       if (size < 0) {
8443 +               errno = EINVAL;
8444 +               return posix_error();
8445 +       }
8446 +       buffer = PyString_FromStringAndSize((char *)NULL, size);
8447 +       if (buffer == NULL)
8448 +               return NULL;
8449 +       Py_BEGIN_ALLOW_THREADS
8450 +       n = read(fd, PyString_AsString(buffer), size);
8451 +       Py_END_ALLOW_THREADS
8452 +       if (n < 0) {
8453 +               Py_DECREF(buffer);
8454 +               return posix_error();
8455 +       }
8456 +       if (n != size)
8457 +               _PyString_Resize(&buffer, n);
8458 +       return buffer;
8459 +}
8460 +
8461 +
8462 +PyDoc_STRVAR(posix_write__doc__,
8463 +"write(fd, string) -> byteswritten\n\n\
8464 +Write a string to a file descriptor.");
8465 +
8466 +static PyObject *
8467 +posix_write(PyObject *self, PyObject *args)
8468 +{
8469 +       int fd;
8470 +       Py_ssize_t size;
8471 +       char *buffer;
8472 +
8473 +       if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
8474 +               return NULL;
8475 +       Py_BEGIN_ALLOW_THREADS
8476 +       size = write(fd, buffer, (size_t)size);
8477 +       Py_END_ALLOW_THREADS
8478 +       if (size < 0)
8479 +               return posix_error();
8480 +       return PyInt_FromSsize_t(size);
8481 +}
8482 +
8483 +
8484 +PyDoc_STRVAR(posix_fstat__doc__,
8485 +"fstat(fd) -> stat result\n\n\
8486 +Like stat(), but for an open file descriptor.");
8487 +
8488 +static PyObject *
8489 +posix_fstat(PyObject *self, PyObject *args)
8490 +{
8491 +       int fd;
8492 +       STRUCT_STAT st;
8493 +       int res;
8494 +       if (!PyArg_ParseTuple(args, "i:fstat", &fd))
8495 +               return NULL;
8496 +#ifdef __VMS
8497 +        /* on OpenVMS we must ensure that all bytes are written to the file */
8498 +        fsync(fd);
8499 +#endif
8500 +       Py_BEGIN_ALLOW_THREADS
8501 +       res = FSTAT(fd, &st);
8502 +       Py_END_ALLOW_THREADS
8503 +       if (res != 0) {
8504 +#ifdef MS_WINDOWS
8505 +               return win32_error("fstat", NULL);
8506 +#else
8507 +               return posix_error();
8508 +#endif
8509 +       }
8510 +
8511 +       return _pystat_fromstructstat(&st);
8512 +}
8513 +
8514 +
8515 +PyDoc_STRVAR(posix_fdopen__doc__,
8516 +"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
8517 +Return an open file object connected to a file descriptor.");
8518 +
8519 +static PyObject *
8520 +posix_fdopen(PyObject *self, PyObject *args)
8521 +{
8522 +       int fd;
8523 +       char *orgmode = "r";
8524 +       int bufsize = -1;
8525 +       FILE *fp;
8526 +       PyObject *f;
8527 +       char *mode;
8528 +       if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
8529 +               return NULL;
8530 +
8531 +       /* Sanitize mode.  See fileobject.c */
8532 +       mode = PyMem_MALLOC(strlen(orgmode)+3);
8533 +       if (!mode) {
8534 +               PyErr_NoMemory();
8535 +               return NULL;
8536 +       }
8537 +       strcpy(mode, orgmode);
8538 +       if (_PyFile_SanitizeMode(mode)) {
8539 +               PyMem_FREE(mode);
8540 +               return NULL;
8541 +       }
8542 +       Py_BEGIN_ALLOW_THREADS
8543 +#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
8544 +       if (mode[0] == 'a') {
8545 +               /* try to make sure the O_APPEND flag is set */
8546 +               int flags;
8547 +               flags = fcntl(fd, F_GETFL);
8548 +               if (flags != -1)
8549 +                       fcntl(fd, F_SETFL, flags | O_APPEND);
8550 +               fp = fdopen(fd, mode);
8551 +               if (fp == NULL && flags != -1)
8552 +                       /* restore old mode if fdopen failed */
8553 +                       fcntl(fd, F_SETFL, flags);
8554 +       } else {
8555 +               fp = fdopen(fd, mode);
8556 +       }
8557 +#else
8558 +       fp = fdopen(fd, mode);
8559 +#endif
8560 +       Py_END_ALLOW_THREADS
8561 +       PyMem_FREE(mode);
8562 +       if (fp == NULL)
8563 +               return posix_error();
8564 +       f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
8565 +       if (f != NULL)
8566 +               PyFile_SetBufSize(f, bufsize);
8567 +       return f;
8568 +}
8569 +
8570 +PyDoc_STRVAR(posix_isatty__doc__,
8571 +"isatty(fd) -> bool\n\n\
8572 +Return True if the file descriptor 'fd' is an open file descriptor\n\
8573 +connected to the slave end of a terminal.");
8574 +
8575 +static PyObject *
8576 +posix_isatty(PyObject *self, PyObject *args)
8577 +{
8578 +       int fd;
8579 +       if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8580 +               return NULL;
8581 +       return PyBool_FromLong(isatty(fd));
8582 +}
8583 +
8584 +#ifdef HAVE_PIPE
8585 +PyDoc_STRVAR(posix_pipe__doc__,
8586 +"pipe() -> (read_end, write_end)\n\n\
8587 +Create a pipe.");
8588 +
8589 +static PyObject *
8590 +posix_pipe(PyObject *self, PyObject *noargs)
8591 +{
8592 +#if defined(PYOS_OS2)
8593 +    HFILE read, write;
8594 +    APIRET rc;
8595 +
8596 +       Py_BEGIN_ALLOW_THREADS
8597 +    rc = DosCreatePipe( &read, &write, 4096);
8598 +       Py_END_ALLOW_THREADS
8599 +    if (rc != NO_ERROR)
8600 +        return os2_error(rc);
8601 +
8602 +    return Py_BuildValue("(ii)", read, write);
8603 +#else
8604 +#if !defined(MS_WINDOWS)
8605 +       int fds[2];
8606 +       int res;
8607 +       Py_BEGIN_ALLOW_THREADS
8608 +       res = pipe(fds);
8609 +       Py_END_ALLOW_THREADS
8610 +       if (res != 0)
8611 +               return posix_error();
8612 +       return Py_BuildValue("(ii)", fds[0], fds[1]);
8613 +#else /* MS_WINDOWS */
8614 +       HANDLE read, write;
8615 +       int read_fd, write_fd;
8616 +       BOOL ok;
8617 +       Py_BEGIN_ALLOW_THREADS
8618 +       ok = CreatePipe(&read, &write, NULL, 0);
8619 +       Py_END_ALLOW_THREADS
8620 +       if (!ok)
8621 +               return win32_error("CreatePipe", NULL);
8622 +       read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8623 +       write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8624 +       return Py_BuildValue("(ii)", read_fd, write_fd);
8625 +#endif /* MS_WINDOWS */
8626 +#endif
8627 +}
8628 +#endif  /* HAVE_PIPE */
8629 +
8630 +
8631 +#ifdef HAVE_MKFIFO
8632 +PyDoc_STRVAR(posix_mkfifo__doc__,
8633 +"mkfifo(filename [, mode=0666])\n\n\
8634 +Create a FIFO (a POSIX named pipe).");
8635 +
8636 +static PyObject *
8637 +posix_mkfifo(PyObject *self, PyObject *args)
8638 +{
8639 +       char *filename;
8640 +       int mode = 0666;
8641 +       int res;
8642 +       if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
8643 +               return NULL;
8644 +       Py_BEGIN_ALLOW_THREADS
8645 +       res = mkfifo(filename, mode);
8646 +       Py_END_ALLOW_THREADS
8647 +       if (res < 0)
8648 +               return posix_error();
8649 +       Py_INCREF(Py_None);
8650 +       return Py_None;
8651 +}
8652 +#endif
8653 +
8654 +
8655 +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8656 +PyDoc_STRVAR(posix_mknod__doc__,
8657 +"mknod(filename [, mode=0600, device])\n\n\
8658 +Create a filesystem node (file, device special file or named pipe)\n\
8659 +named filename. mode specifies both the permissions to use and the\n\
8660 +type of node to be created, being combined (bitwise OR) with one of\n\
8661 +S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
8662 +device defines the newly created device special file (probably using\n\
8663 +os.makedev()), otherwise it is ignored.");
8664 +
8665 +
8666 +static PyObject *
8667 +posix_mknod(PyObject *self, PyObject *args)
8668 +{
8669 +       char *filename;
8670 +       int mode = 0600;
8671 +       int device = 0;
8672 +       int res;
8673 +       if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
8674 +               return NULL;
8675 +       Py_BEGIN_ALLOW_THREADS
8676 +       res = mknod(filename, mode, device);
8677 +       Py_END_ALLOW_THREADS
8678 +       if (res < 0)
8679 +               return posix_error();
8680 +       Py_INCREF(Py_None);
8681 +       return Py_None;
8682 +}
8683 +#endif
8684 +
8685 +#ifdef HAVE_DEVICE_MACROS
8686 +PyDoc_STRVAR(posix_major__doc__,
8687 +"major(device) -> major number\n\
8688 +Extracts a device major number from a raw device number.");
8689 +
8690 +static PyObject *
8691 +posix_major(PyObject *self, PyObject *args)
8692 +{
8693 +       int device;
8694 +       if (!PyArg_ParseTuple(args, "i:major", &device))
8695 +               return NULL;
8696 +       return PyInt_FromLong((long)major(device));
8697 +}
8698 +
8699 +PyDoc_STRVAR(posix_minor__doc__,
8700 +"minor(device) -> minor number\n\
8701 +Extracts a device minor number from a raw device number.");
8702 +
8703 +static PyObject *
8704 +posix_minor(PyObject *self, PyObject *args)
8705 +{
8706 +       int device;
8707 +       if (!PyArg_ParseTuple(args, "i:minor", &device))
8708 +               return NULL;
8709 +       return PyInt_FromLong((long)minor(device));
8710 +}
8711 +
8712 +PyDoc_STRVAR(posix_makedev__doc__,
8713 +"makedev(major, minor) -> device number\n\
8714 +Composes a raw device number from the major and minor device numbers.");
8715 +
8716 +static PyObject *
8717 +posix_makedev(PyObject *self, PyObject *args)
8718 +{
8719 +       int major, minor;
8720 +       if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8721 +               return NULL;
8722 +       return PyInt_FromLong((long)makedev(major, minor));
8723 +}
8724 +#endif /* device macros */
8725 +
8726 +
8727 +#ifdef HAVE_FTRUNCATE
8728 +PyDoc_STRVAR(posix_ftruncate__doc__,
8729 +"ftruncate(fd, length)\n\n\
8730 +Truncate a file to a specified length.");
8731 +
8732 +static PyObject *
8733 +posix_ftruncate(PyObject *self, PyObject *args)
8734 +{
8735 +       int fd;
8736 +       off_t length;
8737 +       int res;
8738 +       PyObject *lenobj;
8739 +
8740 +       if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
8741 +               return NULL;
8742 +
8743 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8744 +       length = PyInt_AsLong(lenobj);
8745 +#else
8746 +       length = PyLong_Check(lenobj) ?
8747 +               PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
8748 +#endif
8749 +       if (PyErr_Occurred())
8750 +               return NULL;
8751 +
8752 +       Py_BEGIN_ALLOW_THREADS
8753 +       res = ftruncate(fd, length);
8754 +       Py_END_ALLOW_THREADS
8755 +       if (res < 0) {
8756 +               PyErr_SetFromErrno(PyExc_IOError);
8757 +               return NULL;
8758 +       }
8759 +       Py_INCREF(Py_None);
8760 +       return Py_None;
8761 +}
8762 +#endif
8763 +
8764 +#ifdef HAVE_PUTENV
8765 +PyDoc_STRVAR(posix_putenv__doc__,
8766 +"putenv(key, value)\n\n\
8767 +Change or add an environment variable.");
8768 +
8769 +/* Save putenv() parameters as values here, so we can collect them when they
8770 + * get re-set with another call for the same key. */
8771 +static PyObject *posix_putenv_garbage;
8772 +
8773 +static PyObject *
8774 +posix_putenv(PyObject *self, PyObject *args)
8775 +{
8776 +        char *s1, *s2;
8777 +        char *newenv;
8778 +       PyObject *newstr;
8779 +       size_t len;
8780 +
8781 +       if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
8782 +               return NULL;
8783 +
8784 +#if defined(PYOS_OS2)
8785 +    if (stricmp(s1, "BEGINLIBPATH") == 0) {
8786 +        APIRET rc;
8787 +
8788 +        rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
8789 +        if (rc != NO_ERROR)
8790 +            return os2_error(rc);
8791 +
8792 +    } else if (stricmp(s1, "ENDLIBPATH") == 0) {
8793 +        APIRET rc;
8794 +
8795 +        rc = DosSetExtLIBPATH(s2, END_LIBPATH);
8796 +        if (rc != NO_ERROR)
8797 +            return os2_error(rc);
8798 +    } else {
8799 +#endif
8800 +
8801 +       /* XXX This can leak memory -- not easy to fix :-( */
8802 +       len = strlen(s1) + strlen(s2) + 2;
8803 +       /* len includes space for a trailing \0; the size arg to
8804 +          PyString_FromStringAndSize does not count that */
8805 +       newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
8806 +       if (newstr == NULL)
8807 +               return PyErr_NoMemory();
8808 +       newenv = PyString_AS_STRING(newstr);
8809 +       PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
8810 +       if (putenv(newenv)) {
8811 +                Py_DECREF(newstr);
8812 +                posix_error();
8813 +                return NULL;
8814 +       }
8815 +       /* Install the first arg and newstr in posix_putenv_garbage;
8816 +        * this will cause previous value to be collected.  This has to
8817 +        * happen after the real putenv() call because the old value
8818 +        * was still accessible until then. */
8819 +       if (PyDict_SetItem(posix_putenv_garbage,
8820 +                          PyTuple_GET_ITEM(args, 0), newstr)) {
8821 +               /* really not much we can do; just leak */
8822 +               PyErr_Clear();
8823 +       }
8824 +       else {
8825 +               Py_DECREF(newstr);
8826 +       }
8827 +
8828 +#if defined(PYOS_OS2)
8829 +    }
8830 +#endif
8831 +       Py_INCREF(Py_None);
8832 +        return Py_None;
8833 +}
8834 +#endif /* putenv */
8835 +
8836 +#ifdef HAVE_UNSETENV
8837 +PyDoc_STRVAR(posix_unsetenv__doc__,
8838 +"unsetenv(key)\n\n\
8839 +Delete an environment variable.");
8840 +
8841 +static PyObject *
8842 +posix_unsetenv(PyObject *self, PyObject *args)
8843 +{
8844 +        char *s1;
8845 +
8846 +       if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
8847 +               return NULL;
8848 +
8849 +       unsetenv(s1);
8850 +
8851 +       /* Remove the key from posix_putenv_garbage;
8852 +        * this will cause it to be collected.  This has to
8853 +        * happen after the real unsetenv() call because the
8854 +        * old value was still accessible until then.
8855 +        */
8856 +       if (PyDict_DelItem(posix_putenv_garbage,
8857 +               PyTuple_GET_ITEM(args, 0))) {
8858 +               /* really not much we can do; just leak */
8859 +               PyErr_Clear();
8860 +       }
8861 +
8862 +       Py_INCREF(Py_None);
8863 +       return Py_None;
8864 +}
8865 +#endif /* unsetenv */
8866 +
8867 +#ifdef HAVE_STRERROR
8868 +PyDoc_STRVAR(posix_strerror__doc__,
8869 +"strerror(code) -> string\n\n\
8870 +Translate an error code to a message string.");
8871 +
8872 +static PyObject *
8873 +posix_strerror(PyObject *self, PyObject *args)
8874 +{
8875 +       int code;
8876 +       char *message;
8877 +       if (!PyArg_ParseTuple(args, "i:strerror", &code))
8878 +               return NULL;
8879 +       message = strerror(code);
8880 +       if (message == NULL) {
8881 +               PyErr_SetString(PyExc_ValueError,
8882 +                               "strerror() argument out of range");
8883 +               return NULL;
8884 +       }
8885 +       return PyString_FromString(message);
8886 +}
8887 +#endif /* strerror */
8888 +
8889 +
8890 +#ifdef HAVE_SYS_WAIT_H
8891 +
8892 +#ifdef WCOREDUMP
8893 +PyDoc_STRVAR(posix_WCOREDUMP__doc__,
8894 +"WCOREDUMP(status) -> bool\n\n\
8895 +Return True if the process returning 'status' was dumped to a core file.");
8896 +
8897 +static PyObject *
8898 +posix_WCOREDUMP(PyObject *self, PyObject *args)
8899 +{
8900 +       WAIT_TYPE status;
8901 +       WAIT_STATUS_INT(status) = 0;
8902 +
8903 +       if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8904 +               return NULL;
8905 +
8906 +       return PyBool_FromLong(WCOREDUMP(status));
8907 +}
8908 +#endif /* WCOREDUMP */
8909 +
8910 +#ifdef WIFCONTINUED
8911 +PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
8912 +"WIFCONTINUED(status) -> bool\n\n\
8913 +Return True if the process returning 'status' was continued from a\n\
8914 +job control stop.");
8915 +
8916 +static PyObject *
8917 +posix_WIFCONTINUED(PyObject *self, PyObject *args)
8918 +{
8919 +       WAIT_TYPE status;
8920 +       WAIT_STATUS_INT(status) = 0;
8921 +
8922 +       if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8923 +               return NULL;
8924 +
8925 +       return PyBool_FromLong(WIFCONTINUED(status));
8926 +}
8927 +#endif /* WIFCONTINUED */
8928 +
8929 +#ifdef WIFSTOPPED
8930 +PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
8931 +"WIFSTOPPED(status) -> bool\n\n\
8932 +Return True if the process returning 'status' was stopped.");
8933 +
8934 +static PyObject *
8935 +posix_WIFSTOPPED(PyObject *self, PyObject *args)
8936 +{
8937 +       WAIT_TYPE status;
8938 +       WAIT_STATUS_INT(status) = 0;
8939 +
8940 +       if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8941 +               return NULL;
8942 +
8943 +       return PyBool_FromLong(WIFSTOPPED(status));
8944 +}
8945 +#endif /* WIFSTOPPED */
8946 +
8947 +#ifdef WIFSIGNALED
8948 +PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
8949 +"WIFSIGNALED(status) -> bool\n\n\
8950 +Return True if the process returning 'status' was terminated by a signal.");
8951 +
8952 +static PyObject *
8953 +posix_WIFSIGNALED(PyObject *self, PyObject *args)
8954 +{
8955 +       WAIT_TYPE status;
8956 +       WAIT_STATUS_INT(status) = 0;
8957 +
8958 +       if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8959 +               return NULL;
8960 +
8961 +       return PyBool_FromLong(WIFSIGNALED(status));
8962 +}
8963 +#endif /* WIFSIGNALED */
8964 +
8965 +#ifdef WIFEXITED
8966 +PyDoc_STRVAR(posix_WIFEXITED__doc__,
8967 +"WIFEXITED(status) -> bool\n\n\
8968 +Return true if the process returning 'status' exited using the exit()\n\
8969 +system call.");
8970 +
8971 +static PyObject *
8972 +posix_WIFEXITED(PyObject *self, PyObject *args)
8973 +{
8974 +       WAIT_TYPE status;
8975 +       WAIT_STATUS_INT(status) = 0;
8976 +
8977 +       if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8978 +               return NULL;
8979 +
8980 +       return PyBool_FromLong(WIFEXITED(status));
8981 +}
8982 +#endif /* WIFEXITED */
8983 +
8984 +#ifdef WEXITSTATUS
8985 +PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
8986 +"WEXITSTATUS(status) -> integer\n\n\
8987 +Return the process return code from 'status'.");
8988 +
8989 +static PyObject *
8990 +posix_WEXITSTATUS(PyObject *self, PyObject *args)
8991 +{
8992 +       WAIT_TYPE status;
8993 +       WAIT_STATUS_INT(status) = 0;
8994 +
8995 +       if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8996 +               return NULL;
8997 +
8998 +       return Py_BuildValue("i", WEXITSTATUS(status));
8999 +}
9000 +#endif /* WEXITSTATUS */
9001 +
9002 +#ifdef WTERMSIG
9003 +PyDoc_STRVAR(posix_WTERMSIG__doc__,
9004 +"WTERMSIG(status) -> integer\n\n\
9005 +Return the signal that terminated the process that provided the 'status'\n\
9006 +value.");
9007 +
9008 +static PyObject *
9009 +posix_WTERMSIG(PyObject *self, PyObject *args)
9010 +{
9011 +       WAIT_TYPE status;
9012 +       WAIT_STATUS_INT(status) = 0;
9013 +
9014 +       if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9015 +               return NULL;
9016 +
9017 +       return Py_BuildValue("i", WTERMSIG(status));
9018 +}
9019 +#endif /* WTERMSIG */
9020 +
9021 +#ifdef WSTOPSIG
9022 +PyDoc_STRVAR(posix_WSTOPSIG__doc__,
9023 +"WSTOPSIG(status) -> integer\n\n\
9024 +Return the signal that stopped the process that provided\n\
9025 +the 'status' value.");
9026 +
9027 +static PyObject *
9028 +posix_WSTOPSIG(PyObject *self, PyObject *args)
9029 +{
9030 +       WAIT_TYPE status;
9031 +       WAIT_STATUS_INT(status) = 0;
9032 +
9033 +       if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9034 +               return NULL;
9035 +
9036 +       return Py_BuildValue("i", WSTOPSIG(status));
9037 +}
9038 +#endif /* WSTOPSIG */
9039 +
9040 +#endif /* HAVE_SYS_WAIT_H */
9041 +
9042 +
9043 +#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
9044 +#ifdef _SCO_DS
9045 +/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9046 +   needed definitions in sys/statvfs.h */
9047 +#define _SVID3
9048 +#endif
9049 +#include <sys/statvfs.h>
9050 +
9051 +static PyObject*
9052 +_pystatvfs_fromstructstatvfs(struct statvfs st) {
9053 +        PyObject *v = PyStructSequence_New(&StatVFSResultType);
9054 +       if (v == NULL)
9055 +               return NULL;
9056 +
9057 +#if !defined(HAVE_LARGEFILE_SUPPORT)
9058 +        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
9059 +        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
9060 +        PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
9061 +        PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
9062 +        PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
9063 +        PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
9064 +        PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
9065 +        PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
9066 +        PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
9067 +        PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
9068 +#else
9069 +        PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
9070 +        PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
9071 +        PyStructSequence_SET_ITEM(v, 2,
9072 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9073 +        PyStructSequence_SET_ITEM(v, 3,
9074 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9075 +        PyStructSequence_SET_ITEM(v, 4,
9076 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9077 +        PyStructSequence_SET_ITEM(v, 5,
9078 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9079 +        PyStructSequence_SET_ITEM(v, 6,
9080 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9081 +        PyStructSequence_SET_ITEM(v, 7,
9082 +                              PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9083 +        PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
9084 +        PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
9085 +#endif
9086 +
9087 +        return v;
9088 +}
9089 +
9090 +PyDoc_STRVAR(posix_fstatvfs__doc__,
9091 +"fstatvfs(fd) -> statvfs result\n\n\
9092 +Perform an fstatvfs system call on the given fd.");
9093 +
9094 +static PyObject *
9095 +posix_fstatvfs(PyObject *self, PyObject *args)
9096 +{
9097 +       int fd, res;
9098 +       struct statvfs st;
9099 +
9100 +       if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9101 +               return NULL;
9102 +       Py_BEGIN_ALLOW_THREADS
9103 +       res = fstatvfs(fd, &st);
9104 +       Py_END_ALLOW_THREADS
9105 +       if (res != 0)
9106 +               return posix_error();
9107 +
9108 +        return _pystatvfs_fromstructstatvfs(st);
9109 +}
9110 +#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
9111 +
9112 +
9113 +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
9114 +#include <sys/statvfs.h>
9115 +
9116 +PyDoc_STRVAR(posix_statvfs__doc__,
9117 +"statvfs(path) -> statvfs result\n\n\
9118 +Perform a statvfs system call on the given path.");
9119 +
9120 +static PyObject *
9121 +posix_statvfs(PyObject *self, PyObject *args)
9122 +{
9123 +       char *path;
9124 +       int res;
9125 +       struct statvfs st;
9126 +       if (!PyArg_ParseTuple(args, "s:statvfs", &path))
9127 +               return NULL;
9128 +       Py_BEGIN_ALLOW_THREADS
9129 +       res = statvfs(path, &st);
9130 +       Py_END_ALLOW_THREADS
9131 +       if (res != 0)
9132 +               return posix_error_with_filename(path);
9133 +
9134 +        return _pystatvfs_fromstructstatvfs(st);
9135 +}
9136 +#endif /* HAVE_STATVFS */
9137 +
9138 +
9139 +#ifdef HAVE_TEMPNAM
9140 +PyDoc_STRVAR(posix_tempnam__doc__,
9141 +"tempnam([dir[, prefix]]) -> string\n\n\
9142 +Return a unique name for a temporary file.\n\
9143 +The directory and a prefix may be specified as strings; they may be omitted\n\
9144 +or None if not needed.");
9145 +
9146 +static PyObject *
9147 +posix_tempnam(PyObject *self, PyObject *args)
9148 +{
9149 +    PyObject *result = NULL;
9150 +    char *dir = NULL;
9151 +    char *pfx = NULL;
9152 +    char *name;
9153 +
9154 +    if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
9155 +        return NULL;
9156 +
9157 +    if (PyErr_Warn(PyExc_RuntimeWarning,
9158 +                 "tempnam is a potential security risk to your program") < 0)
9159 +           return NULL;
9160 +
9161 +#ifdef MS_WINDOWS
9162 +    name = _tempnam(dir, pfx);
9163 +#else
9164 +    name = tempnam(dir, pfx);
9165 +#endif
9166 +    if (name == NULL)
9167 +        return PyErr_NoMemory();
9168 +    result = PyString_FromString(name);
9169 +    free(name);
9170 +    return result;
9171 +}
9172 +#endif
9173 +
9174 +
9175 +#ifdef HAVE_TMPFILE
9176 +PyDoc_STRVAR(posix_tmpfile__doc__,
9177 +"tmpfile() -> file object\n\n\
9178 +Create a temporary file with no directory entries.");
9179 +
9180 +static PyObject *
9181 +posix_tmpfile(PyObject *self, PyObject *noargs)
9182 +{
9183 +    FILE *fp;
9184 +
9185 +    fp = tmpfile();
9186 +    if (fp == NULL)
9187 +        return posix_error();
9188 +    return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
9189 +}
9190 +#endif
9191 +
9192 +
9193 +#ifdef HAVE_TMPNAM
9194 +PyDoc_STRVAR(posix_tmpnam__doc__,
9195 +"tmpnam() -> string\n\n\
9196 +Return a unique name for a temporary file.");
9197 +
9198 +static PyObject *
9199 +posix_tmpnam(PyObject *self, PyObject *noargs)
9200 +{
9201 +    char buffer[L_tmpnam];
9202 +    char *name;
9203 +
9204 +    if (PyErr_Warn(PyExc_RuntimeWarning,
9205 +                 "tmpnam is a potential security risk to your program") < 0)
9206 +           return NULL;
9207 +
9208 +#ifdef USE_TMPNAM_R
9209 +    name = tmpnam_r(buffer);
9210 +#else
9211 +    name = tmpnam(buffer);
9212 +#endif
9213 +    if (name == NULL) {
9214 +       PyObject *err = Py_BuildValue("is", 0,
9215 +#ifdef USE_TMPNAM_R
9216 +                                      "unexpected NULL from tmpnam_r"
9217 +#else
9218 +                                      "unexpected NULL from tmpnam"
9219 +#endif
9220 +                                      );
9221 +       PyErr_SetObject(PyExc_OSError, err);
9222 +       Py_XDECREF(err);
9223 +       return NULL;
9224 +    }
9225 +    return PyString_FromString(buffer);
9226 +}
9227 +#endif
9228 +
9229 +
9230 +/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9231 + * It maps strings representing configuration variable names to
9232 + * integer values, allowing those functions to be called with the
9233 + * magic names instead of polluting the module's namespace with tons of
9234 + * rarely-used constants.  There are three separate tables that use
9235 + * these definitions.
9236 + *
9237 + * This code is always included, even if none of the interfaces that
9238 + * need it are included.  The #if hackery needed to avoid it would be
9239 + * sufficiently pervasive that it's not worth the loss of readability.
9240 + */
9241 +struct constdef {
9242 +    char *name;
9243 +    long value;
9244 +};
9245 +
9246 +static int
9247 +conv_confname(PyObject *arg, int *valuep, struct constdef *table,
9248 +             size_t tablesize)
9249 +{
9250 +    if (PyInt_Check(arg)) {
9251 +        *valuep = PyInt_AS_LONG(arg);
9252 +        return 1;
9253 +    }
9254 +    if (PyString_Check(arg)) {
9255 +        /* look up the value in the table using a binary search */
9256 +        size_t lo = 0;
9257 +               size_t mid;
9258 +        size_t hi = tablesize;
9259 +        int cmp;
9260 +        char *confname = PyString_AS_STRING(arg);
9261 +        while (lo < hi) {
9262 +            mid = (lo + hi) / 2;
9263 +            cmp = strcmp(confname, table[mid].name);
9264 +            if (cmp < 0)
9265 +                hi = mid;
9266 +            else if (cmp > 0)
9267 +                lo = mid + 1;
9268 +            else {
9269 +                *valuep = table[mid].value;
9270 +                return 1;
9271 +            }
9272 +        }
9273 +        PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9274 +    }
9275 +    else
9276 +        PyErr_SetString(PyExc_TypeError,
9277 +                        "configuration names must be strings or integers");
9278 +    return 0;
9279 +}
9280 +
9281 +
9282 +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9283 +static struct constdef  posix_constants_pathconf[] = {
9284 +#ifdef _PC_ABI_AIO_XFER_MAX
9285 +    {"PC_ABI_AIO_XFER_MAX",    _PC_ABI_AIO_XFER_MAX},
9286 +#endif
9287 +#ifdef _PC_ABI_ASYNC_IO
9288 +    {"PC_ABI_ASYNC_IO",        _PC_ABI_ASYNC_IO},
9289 +#endif
9290 +#ifdef _PC_ASYNC_IO
9291 +    {"PC_ASYNC_IO",    _PC_ASYNC_IO},
9292 +#endif
9293 +#ifdef _PC_CHOWN_RESTRICTED
9294 +    {"PC_CHOWN_RESTRICTED",    _PC_CHOWN_RESTRICTED},
9295 +#endif
9296 +#ifdef _PC_FILESIZEBITS
9297 +    {"PC_FILESIZEBITS",        _PC_FILESIZEBITS},
9298 +#endif
9299 +#ifdef _PC_LAST
9300 +    {"PC_LAST",        _PC_LAST},
9301 +#endif
9302 +#ifdef _PC_LINK_MAX
9303 +    {"PC_LINK_MAX",    _PC_LINK_MAX},
9304 +#endif
9305 +#ifdef _PC_MAX_CANON
9306 +    {"PC_MAX_CANON",   _PC_MAX_CANON},
9307 +#endif
9308 +#ifdef _PC_MAX_INPUT
9309 +    {"PC_MAX_INPUT",   _PC_MAX_INPUT},
9310 +#endif
9311 +#ifdef _PC_NAME_MAX
9312 +    {"PC_NAME_MAX",    _PC_NAME_MAX},
9313 +#endif
9314 +#ifdef _PC_NO_TRUNC
9315 +    {"PC_NO_TRUNC",    _PC_NO_TRUNC},
9316 +#endif
9317 +#ifdef _PC_PATH_MAX
9318 +    {"PC_PATH_MAX",    _PC_PATH_MAX},
9319 +#endif
9320 +#ifdef _PC_PIPE_BUF
9321 +    {"PC_PIPE_BUF",    _PC_PIPE_BUF},
9322 +#endif
9323 +#ifdef _PC_PRIO_IO
9324 +    {"PC_PRIO_IO",     _PC_PRIO_IO},
9325 +#endif
9326 +#ifdef _PC_SOCK_MAXBUF
9327 +    {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
9328 +#endif
9329 +#ifdef _PC_SYNC_IO
9330 +    {"PC_SYNC_IO",     _PC_SYNC_IO},
9331 +#endif
9332 +#ifdef _PC_VDISABLE
9333 +    {"PC_VDISABLE",    _PC_VDISABLE},
9334 +#endif
9335 +};
9336 +
9337 +static int
9338 +conv_path_confname(PyObject *arg, int *valuep)
9339 +{
9340 +    return conv_confname(arg, valuep, posix_constants_pathconf,
9341 +                         sizeof(posix_constants_pathconf)
9342 +                           / sizeof(struct constdef));
9343 +}
9344 +#endif
9345 +
9346 +#ifdef HAVE_FPATHCONF
9347 +PyDoc_STRVAR(posix_fpathconf__doc__,
9348 +"fpathconf(fd, name) -> integer\n\n\
9349 +Return the configuration limit name for the file descriptor fd.\n\
9350 +If there is no limit, return -1.");
9351 +
9352 +static PyObject *
9353 +posix_fpathconf(PyObject *self, PyObject *args)
9354 +{
9355 +    PyObject *result = NULL;
9356 +    int name, fd;
9357 +
9358 +    if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9359 +                         conv_path_confname, &name)) {
9360 +        long limit;
9361 +
9362 +        errno = 0;
9363 +        limit = fpathconf(fd, name);
9364 +        if (limit == -1 && errno != 0)
9365 +            posix_error();
9366 +        else
9367 +            result = PyInt_FromLong(limit);
9368 +    }
9369 +    return result;
9370 +}
9371 +#endif
9372 +
9373 +
9374 +#ifdef HAVE_PATHCONF
9375 +PyDoc_STRVAR(posix_pathconf__doc__,
9376 +"pathconf(path, name) -> integer\n\n\
9377 +Return the configuration limit name for the file or directory path.\n\
9378 +If there is no limit, return -1.");
9379 +
9380 +static PyObject *
9381 +posix_pathconf(PyObject *self, PyObject *args)
9382 +{
9383 +    PyObject *result = NULL;
9384 +    int name;
9385 +    char *path;
9386 +
9387 +    if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
9388 +                         conv_path_confname, &name)) {
9389 +        long limit;
9390 +
9391 +        errno = 0;
9392 +        limit = pathconf(path, name);
9393 +        if (limit == -1 && errno != 0) {
9394 +            if (errno == EINVAL)
9395 +                /* could be a path or name problem */
9396 +                posix_error();
9397 +            else
9398 +                posix_error_with_filename(path);
9399 +        }
9400 +        else
9401 +            result = PyInt_FromLong(limit);
9402 +    }
9403 +    return result;
9404 +}
9405 +#endif
9406 +
9407 +#ifdef HAVE_CONFSTR
9408 +static struct constdef posix_constants_confstr[] = {
9409 +#ifdef _CS_ARCHITECTURE
9410 +    {"CS_ARCHITECTURE",        _CS_ARCHITECTURE},
9411 +#endif
9412 +#ifdef _CS_HOSTNAME
9413 +    {"CS_HOSTNAME",    _CS_HOSTNAME},
9414 +#endif
9415 +#ifdef _CS_HW_PROVIDER
9416 +    {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
9417 +#endif
9418 +#ifdef _CS_HW_SERIAL
9419 +    {"CS_HW_SERIAL",   _CS_HW_SERIAL},
9420 +#endif
9421 +#ifdef _CS_INITTAB_NAME
9422 +    {"CS_INITTAB_NAME",        _CS_INITTAB_NAME},
9423 +#endif
9424 +#ifdef _CS_LFS64_CFLAGS
9425 +    {"CS_LFS64_CFLAGS",        _CS_LFS64_CFLAGS},
9426 +#endif
9427 +#ifdef _CS_LFS64_LDFLAGS
9428 +    {"CS_LFS64_LDFLAGS",       _CS_LFS64_LDFLAGS},
9429 +#endif
9430 +#ifdef _CS_LFS64_LIBS
9431 +    {"CS_LFS64_LIBS",  _CS_LFS64_LIBS},
9432 +#endif
9433 +#ifdef _CS_LFS64_LINTFLAGS
9434 +    {"CS_LFS64_LINTFLAGS",     _CS_LFS64_LINTFLAGS},
9435 +#endif
9436 +#ifdef _CS_LFS_CFLAGS
9437 +    {"CS_LFS_CFLAGS",  _CS_LFS_CFLAGS},
9438 +#endif
9439 +#ifdef _CS_LFS_LDFLAGS
9440 +    {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
9441 +#endif
9442 +#ifdef _CS_LFS_LIBS
9443 +    {"CS_LFS_LIBS",    _CS_LFS_LIBS},
9444 +#endif
9445 +#ifdef _CS_LFS_LINTFLAGS
9446 +    {"CS_LFS_LINTFLAGS",       _CS_LFS_LINTFLAGS},
9447 +#endif
9448 +#ifdef _CS_MACHINE
9449 +    {"CS_MACHINE",     _CS_MACHINE},
9450 +#endif
9451 +#ifdef _CS_PATH
9452 +    {"CS_PATH",        _CS_PATH},
9453 +#endif
9454 +#ifdef _CS_RELEASE
9455 +    {"CS_RELEASE",     _CS_RELEASE},
9456 +#endif
9457 +#ifdef _CS_SRPC_DOMAIN
9458 +    {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
9459 +#endif
9460 +#ifdef _CS_SYSNAME
9461 +    {"CS_SYSNAME",     _CS_SYSNAME},
9462 +#endif
9463 +#ifdef _CS_VERSION
9464 +    {"CS_VERSION",     _CS_VERSION},
9465 +#endif
9466 +#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
9467 +    {"CS_XBS5_ILP32_OFF32_CFLAGS",     _CS_XBS5_ILP32_OFF32_CFLAGS},
9468 +#endif
9469 +#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
9470 +    {"CS_XBS5_ILP32_OFF32_LDFLAGS",    _CS_XBS5_ILP32_OFF32_LDFLAGS},
9471 +#endif
9472 +#ifdef _CS_XBS5_ILP32_OFF32_LIBS
9473 +    {"CS_XBS5_ILP32_OFF32_LIBS",       _CS_XBS5_ILP32_OFF32_LIBS},
9474 +#endif
9475 +#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
9476 +    {"CS_XBS5_ILP32_OFF32_LINTFLAGS",  _CS_XBS5_ILP32_OFF32_LINTFLAGS},
9477 +#endif
9478 +#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
9479 +    {"CS_XBS5_ILP32_OFFBIG_CFLAGS",    _CS_XBS5_ILP32_OFFBIG_CFLAGS},
9480 +#endif
9481 +#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
9482 +    {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",   _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
9483 +#endif
9484 +#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
9485 +    {"CS_XBS5_ILP32_OFFBIG_LIBS",      _CS_XBS5_ILP32_OFFBIG_LIBS},
9486 +#endif
9487 +#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
9488 +    {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
9489 +#endif
9490 +#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
9491 +    {"CS_XBS5_LP64_OFF64_CFLAGS",      _CS_XBS5_LP64_OFF64_CFLAGS},
9492 +#endif
9493 +#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
9494 +    {"CS_XBS5_LP64_OFF64_LDFLAGS",     _CS_XBS5_LP64_OFF64_LDFLAGS},
9495 +#endif
9496 +#ifdef _CS_XBS5_LP64_OFF64_LIBS
9497 +    {"CS_XBS5_LP64_OFF64_LIBS",        _CS_XBS5_LP64_OFF64_LIBS},
9498 +#endif
9499 +#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
9500 +    {"CS_XBS5_LP64_OFF64_LINTFLAGS",   _CS_XBS5_LP64_OFF64_LINTFLAGS},
9501 +#endif
9502 +#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
9503 +    {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",    _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
9504 +#endif
9505 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
9506 +    {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",   _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
9507 +#endif
9508 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
9509 +    {"CS_XBS5_LPBIG_OFFBIG_LIBS",      _CS_XBS5_LPBIG_OFFBIG_LIBS},
9510 +#endif
9511 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
9512 +    {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
9513 +#endif
9514 +#ifdef _MIPS_CS_AVAIL_PROCESSORS
9515 +    {"MIPS_CS_AVAIL_PROCESSORS",       _MIPS_CS_AVAIL_PROCESSORS},
9516 +#endif
9517 +#ifdef _MIPS_CS_BASE
9518 +    {"MIPS_CS_BASE",   _MIPS_CS_BASE},
9519 +#endif
9520 +#ifdef _MIPS_CS_HOSTID
9521 +    {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
9522 +#endif
9523 +#ifdef _MIPS_CS_HW_NAME
9524 +    {"MIPS_CS_HW_NAME",        _MIPS_CS_HW_NAME},
9525 +#endif
9526 +#ifdef _MIPS_CS_NUM_PROCESSORS
9527 +    {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
9528 +#endif
9529 +#ifdef _MIPS_CS_OSREL_MAJ
9530 +    {"MIPS_CS_OSREL_MAJ",      _MIPS_CS_OSREL_MAJ},
9531 +#endif
9532 +#ifdef _MIPS_CS_OSREL_MIN
9533 +    {"MIPS_CS_OSREL_MIN",      _MIPS_CS_OSREL_MIN},
9534 +#endif
9535 +#ifdef _MIPS_CS_OSREL_PATCH
9536 +    {"MIPS_CS_OSREL_PATCH",    _MIPS_CS_OSREL_PATCH},
9537 +#endif
9538 +#ifdef _MIPS_CS_OS_NAME
9539 +    {"MIPS_CS_OS_NAME",        _MIPS_CS_OS_NAME},
9540 +#endif
9541 +#ifdef _MIPS_CS_OS_PROVIDER
9542 +    {"MIPS_CS_OS_PROVIDER",    _MIPS_CS_OS_PROVIDER},
9543 +#endif
9544 +#ifdef _MIPS_CS_PROCESSORS
9545 +    {"MIPS_CS_PROCESSORS",     _MIPS_CS_PROCESSORS},
9546 +#endif
9547 +#ifdef _MIPS_CS_SERIAL
9548 +    {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
9549 +#endif
9550 +#ifdef _MIPS_CS_VENDOR
9551 +    {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
9552 +#endif
9553 +};
9554 +
9555 +static int
9556 +conv_confstr_confname(PyObject *arg, int *valuep)
9557 +{
9558 +    return conv_confname(arg, valuep, posix_constants_confstr,
9559 +                         sizeof(posix_constants_confstr)
9560 +                           / sizeof(struct constdef));
9561 +}
9562 +
9563 +PyDoc_STRVAR(posix_confstr__doc__,
9564 +"confstr(name) -> string\n\n\
9565 +Return a string-valued system configuration variable.");
9566 +
9567 +static PyObject *
9568 +posix_confstr(PyObject *self, PyObject *args)
9569 +{
9570 +    PyObject *result = NULL;
9571 +    int name;
9572 +    char buffer[256];
9573 +
9574 +    if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
9575 +       int len;
9576 +
9577 +        errno = 0;
9578 +       len = confstr(name, buffer, sizeof(buffer));
9579 +       if (len == 0) {
9580 +           if (errno) {
9581 +               posix_error();
9582 +           }
9583 +           else {
9584 +               result = Py_None;
9585 +               Py_INCREF(Py_None);
9586 +           }
9587 +        }
9588 +        else {
9589 +           if ((unsigned int)len >= sizeof(buffer)) {
9590 +                result = PyString_FromStringAndSize(NULL, len-1);
9591 +                if (result != NULL)
9592 +                    confstr(name, PyString_AS_STRING(result), len);
9593 +            }
9594 +            else
9595 +                result = PyString_FromStringAndSize(buffer, len-1);
9596 +        }
9597 +    }
9598 +    return result;
9599 +}
9600 +#endif
9601 +
9602 +
9603 +#ifdef HAVE_SYSCONF
9604 +static struct constdef posix_constants_sysconf[] = {
9605 +#ifdef _SC_2_CHAR_TERM
9606 +    {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
9607 +#endif
9608 +#ifdef _SC_2_C_BIND
9609 +    {"SC_2_C_BIND",    _SC_2_C_BIND},
9610 +#endif
9611 +#ifdef _SC_2_C_DEV
9612 +    {"SC_2_C_DEV",     _SC_2_C_DEV},
9613 +#endif
9614 +#ifdef _SC_2_C_VERSION
9615 +    {"SC_2_C_VERSION", _SC_2_C_VERSION},
9616 +#endif
9617 +#ifdef _SC_2_FORT_DEV
9618 +    {"SC_2_FORT_DEV",  _SC_2_FORT_DEV},
9619 +#endif
9620 +#ifdef _SC_2_FORT_RUN
9621 +    {"SC_2_FORT_RUN",  _SC_2_FORT_RUN},
9622 +#endif
9623 +#ifdef _SC_2_LOCALEDEF
9624 +    {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
9625 +#endif
9626 +#ifdef _SC_2_SW_DEV
9627 +    {"SC_2_SW_DEV",    _SC_2_SW_DEV},
9628 +#endif
9629 +#ifdef _SC_2_UPE
9630 +    {"SC_2_UPE",       _SC_2_UPE},
9631 +#endif
9632 +#ifdef _SC_2_VERSION
9633 +    {"SC_2_VERSION",   _SC_2_VERSION},
9634 +#endif
9635 +#ifdef _SC_ABI_ASYNCHRONOUS_IO
9636 +    {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
9637 +#endif
9638 +#ifdef _SC_ACL
9639 +    {"SC_ACL", _SC_ACL},
9640 +#endif
9641 +#ifdef _SC_AIO_LISTIO_MAX
9642 +    {"SC_AIO_LISTIO_MAX",      _SC_AIO_LISTIO_MAX},
9643 +#endif
9644 +#ifdef _SC_AIO_MAX
9645 +    {"SC_AIO_MAX",     _SC_AIO_MAX},
9646 +#endif
9647 +#ifdef _SC_AIO_PRIO_DELTA_MAX
9648 +    {"SC_AIO_PRIO_DELTA_MAX",  _SC_AIO_PRIO_DELTA_MAX},
9649 +#endif
9650 +#ifdef _SC_ARG_MAX
9651 +    {"SC_ARG_MAX",     _SC_ARG_MAX},
9652 +#endif
9653 +#ifdef _SC_ASYNCHRONOUS_IO
9654 +    {"SC_ASYNCHRONOUS_IO",     _SC_ASYNCHRONOUS_IO},
9655 +#endif
9656 +#ifdef _SC_ATEXIT_MAX
9657 +    {"SC_ATEXIT_MAX",  _SC_ATEXIT_MAX},
9658 +#endif
9659 +#ifdef _SC_AUDIT
9660 +    {"SC_AUDIT",       _SC_AUDIT},
9661 +#endif
9662 +#ifdef _SC_AVPHYS_PAGES
9663 +    {"SC_AVPHYS_PAGES",        _SC_AVPHYS_PAGES},
9664 +#endif
9665 +#ifdef _SC_BC_BASE_MAX
9666 +    {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
9667 +#endif
9668 +#ifdef _SC_BC_DIM_MAX
9669 +    {"SC_BC_DIM_MAX",  _SC_BC_DIM_MAX},
9670 +#endif
9671 +#ifdef _SC_BC_SCALE_MAX
9672 +    {"SC_BC_SCALE_MAX",        _SC_BC_SCALE_MAX},
9673 +#endif
9674 +#ifdef _SC_BC_STRING_MAX
9675 +    {"SC_BC_STRING_MAX",       _SC_BC_STRING_MAX},
9676 +#endif
9677 +#ifdef _SC_CAP
9678 +    {"SC_CAP", _SC_CAP},
9679 +#endif
9680 +#ifdef _SC_CHARCLASS_NAME_MAX
9681 +    {"SC_CHARCLASS_NAME_MAX",  _SC_CHARCLASS_NAME_MAX},
9682 +#endif
9683 +#ifdef _SC_CHAR_BIT
9684 +    {"SC_CHAR_BIT",    _SC_CHAR_BIT},
9685 +#endif
9686 +#ifdef _SC_CHAR_MAX
9687 +    {"SC_CHAR_MAX",    _SC_CHAR_MAX},
9688 +#endif
9689 +#ifdef _SC_CHAR_MIN
9690 +    {"SC_CHAR_MIN",    _SC_CHAR_MIN},
9691 +#endif
9692 +#ifdef _SC_CHILD_MAX
9693 +    {"SC_CHILD_MAX",   _SC_CHILD_MAX},
9694 +#endif
9695 +#ifdef _SC_CLK_TCK
9696 +    {"SC_CLK_TCK",     _SC_CLK_TCK},
9697 +#endif
9698 +#ifdef _SC_COHER_BLKSZ
9699 +    {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
9700 +#endif
9701 +#ifdef _SC_COLL_WEIGHTS_MAX
9702 +    {"SC_COLL_WEIGHTS_MAX",    _SC_COLL_WEIGHTS_MAX},
9703 +#endif
9704 +#ifdef _SC_DCACHE_ASSOC
9705 +    {"SC_DCACHE_ASSOC",        _SC_DCACHE_ASSOC},
9706 +#endif
9707 +#ifdef _SC_DCACHE_BLKSZ
9708 +    {"SC_DCACHE_BLKSZ",        _SC_DCACHE_BLKSZ},
9709 +#endif
9710 +#ifdef _SC_DCACHE_LINESZ
9711 +    {"SC_DCACHE_LINESZ",       _SC_DCACHE_LINESZ},
9712 +#endif
9713 +#ifdef _SC_DCACHE_SZ
9714 +    {"SC_DCACHE_SZ",   _SC_DCACHE_SZ},
9715 +#endif
9716 +#ifdef _SC_DCACHE_TBLKSZ
9717 +    {"SC_DCACHE_TBLKSZ",       _SC_DCACHE_TBLKSZ},
9718 +#endif
9719 +#ifdef _SC_DELAYTIMER_MAX
9720 +    {"SC_DELAYTIMER_MAX",      _SC_DELAYTIMER_MAX},
9721 +#endif
9722 +#ifdef _SC_EQUIV_CLASS_MAX
9723 +    {"SC_EQUIV_CLASS_MAX",     _SC_EQUIV_CLASS_MAX},
9724 +#endif
9725 +#ifdef _SC_EXPR_NEST_MAX
9726 +    {"SC_EXPR_NEST_MAX",       _SC_EXPR_NEST_MAX},
9727 +#endif
9728 +#ifdef _SC_FSYNC
9729 +    {"SC_FSYNC",       _SC_FSYNC},
9730 +#endif
9731 +#ifdef _SC_GETGR_R_SIZE_MAX
9732 +    {"SC_GETGR_R_SIZE_MAX",    _SC_GETGR_R_SIZE_MAX},
9733 +#endif
9734 +#ifdef _SC_GETPW_R_SIZE_MAX
9735 +    {"SC_GETPW_R_SIZE_MAX",    _SC_GETPW_R_SIZE_MAX},
9736 +#endif
9737 +#ifdef _SC_ICACHE_ASSOC
9738 +    {"SC_ICACHE_ASSOC",        _SC_ICACHE_ASSOC},
9739 +#endif
9740 +#ifdef _SC_ICACHE_BLKSZ
9741 +    {"SC_ICACHE_BLKSZ",        _SC_ICACHE_BLKSZ},
9742 +#endif
9743 +#ifdef _SC_ICACHE_LINESZ
9744 +    {"SC_ICACHE_LINESZ",       _SC_ICACHE_LINESZ},
9745 +#endif
9746 +#ifdef _SC_ICACHE_SZ
9747 +    {"SC_ICACHE_SZ",   _SC_ICACHE_SZ},
9748 +#endif
9749 +#ifdef _SC_INF
9750 +    {"SC_INF", _SC_INF},
9751 +#endif
9752 +#ifdef _SC_INT_MAX
9753 +    {"SC_INT_MAX",     _SC_INT_MAX},
9754 +#endif
9755 +#ifdef _SC_INT_MIN
9756 +    {"SC_INT_MIN",     _SC_INT_MIN},
9757 +#endif
9758 +#ifdef _SC_IOV_MAX
9759 +    {"SC_IOV_MAX",     _SC_IOV_MAX},
9760 +#endif
9761 +#ifdef _SC_IP_SECOPTS
9762 +    {"SC_IP_SECOPTS",  _SC_IP_SECOPTS},
9763 +#endif
9764 +#ifdef _SC_JOB_CONTROL
9765 +    {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
9766 +#endif
9767 +#ifdef _SC_KERN_POINTERS
9768 +    {"SC_KERN_POINTERS",       _SC_KERN_POINTERS},
9769 +#endif
9770 +#ifdef _SC_KERN_SIM
9771 +    {"SC_KERN_SIM",    _SC_KERN_SIM},
9772 +#endif
9773 +#ifdef _SC_LINE_MAX
9774 +    {"SC_LINE_MAX",    _SC_LINE_MAX},
9775 +#endif
9776 +#ifdef _SC_LOGIN_NAME_MAX
9777 +    {"SC_LOGIN_NAME_MAX",      _SC_LOGIN_NAME_MAX},
9778 +#endif
9779 +#ifdef _SC_LOGNAME_MAX
9780 +    {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
9781 +#endif
9782 +#ifdef _SC_LONG_BIT
9783 +    {"SC_LONG_BIT",    _SC_LONG_BIT},
9784 +#endif
9785 +#ifdef _SC_MAC
9786 +    {"SC_MAC", _SC_MAC},
9787 +#endif
9788 +#ifdef _SC_MAPPED_FILES
9789 +    {"SC_MAPPED_FILES",        _SC_MAPPED_FILES},
9790 +#endif
9791 +#ifdef _SC_MAXPID
9792 +    {"SC_MAXPID",      _SC_MAXPID},
9793 +#endif
9794 +#ifdef _SC_MB_LEN_MAX
9795 +    {"SC_MB_LEN_MAX",  _SC_MB_LEN_MAX},
9796 +#endif
9797 +#ifdef _SC_MEMLOCK
9798 +    {"SC_MEMLOCK",     _SC_MEMLOCK},
9799 +#endif
9800 +#ifdef _SC_MEMLOCK_RANGE
9801 +    {"SC_MEMLOCK_RANGE",       _SC_MEMLOCK_RANGE},
9802 +#endif
9803 +#ifdef _SC_MEMORY_PROTECTION
9804 +    {"SC_MEMORY_PROTECTION",   _SC_MEMORY_PROTECTION},
9805 +#endif
9806 +#ifdef _SC_MESSAGE_PASSING
9807 +    {"SC_MESSAGE_PASSING",     _SC_MESSAGE_PASSING},
9808 +#endif
9809 +#ifdef _SC_MMAP_FIXED_ALIGNMENT
9810 +    {"SC_MMAP_FIXED_ALIGNMENT",        _SC_MMAP_FIXED_ALIGNMENT},
9811 +#endif
9812 +#ifdef _SC_MQ_OPEN_MAX
9813 +    {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
9814 +#endif
9815 +#ifdef _SC_MQ_PRIO_MAX
9816 +    {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
9817 +#endif
9818 +#ifdef _SC_NACLS_MAX
9819 +    {"SC_NACLS_MAX",   _SC_NACLS_MAX},
9820 +#endif
9821 +#ifdef _SC_NGROUPS_MAX
9822 +    {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
9823 +#endif
9824 +#ifdef _SC_NL_ARGMAX
9825 +    {"SC_NL_ARGMAX",   _SC_NL_ARGMAX},
9826 +#endif
9827 +#ifdef _SC_NL_LANGMAX
9828 +    {"SC_NL_LANGMAX",  _SC_NL_LANGMAX},
9829 +#endif
9830 +#ifdef _SC_NL_MSGMAX
9831 +    {"SC_NL_MSGMAX",   _SC_NL_MSGMAX},
9832 +#endif
9833 +#ifdef _SC_NL_NMAX
9834 +    {"SC_NL_NMAX",     _SC_NL_NMAX},
9835 +#endif
9836 +#ifdef _SC_NL_SETMAX
9837 +    {"SC_NL_SETMAX",   _SC_NL_SETMAX},
9838 +#endif
9839 +#ifdef _SC_NL_TEXTMAX
9840 +    {"SC_NL_TEXTMAX",  _SC_NL_TEXTMAX},
9841 +#endif
9842 +#ifdef _SC_NPROCESSORS_CONF
9843 +    {"SC_NPROCESSORS_CONF",    _SC_NPROCESSORS_CONF},
9844 +#endif
9845 +#ifdef _SC_NPROCESSORS_ONLN
9846 +    {"SC_NPROCESSORS_ONLN",    _SC_NPROCESSORS_ONLN},
9847 +#endif
9848 +#ifdef _SC_NPROC_CONF
9849 +    {"SC_NPROC_CONF",  _SC_NPROC_CONF},
9850 +#endif
9851 +#ifdef _SC_NPROC_ONLN
9852 +    {"SC_NPROC_ONLN",  _SC_NPROC_ONLN},
9853 +#endif
9854 +#ifdef _SC_NZERO
9855 +    {"SC_NZERO",       _SC_NZERO},
9856 +#endif
9857 +#ifdef _SC_OPEN_MAX
9858 +    {"SC_OPEN_MAX",    _SC_OPEN_MAX},
9859 +#endif
9860 +#ifdef _SC_PAGESIZE
9861 +    {"SC_PAGESIZE",    _SC_PAGESIZE},
9862 +#endif
9863 +#ifdef _SC_PAGE_SIZE
9864 +    {"SC_PAGE_SIZE",   _SC_PAGE_SIZE},
9865 +#endif
9866 +#ifdef _SC_PASS_MAX
9867 +    {"SC_PASS_MAX",    _SC_PASS_MAX},
9868 +#endif
9869 +#ifdef _SC_PHYS_PAGES
9870 +    {"SC_PHYS_PAGES",  _SC_PHYS_PAGES},
9871 +#endif
9872 +#ifdef _SC_PII
9873 +    {"SC_PII", _SC_PII},
9874 +#endif
9875 +#ifdef _SC_PII_INTERNET
9876 +    {"SC_PII_INTERNET",        _SC_PII_INTERNET},
9877 +#endif
9878 +#ifdef _SC_PII_INTERNET_DGRAM
9879 +    {"SC_PII_INTERNET_DGRAM",  _SC_PII_INTERNET_DGRAM},
9880 +#endif
9881 +#ifdef _SC_PII_INTERNET_STREAM
9882 +    {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
9883 +#endif
9884 +#ifdef _SC_PII_OSI
9885 +    {"SC_PII_OSI",     _SC_PII_OSI},
9886 +#endif
9887 +#ifdef _SC_PII_OSI_CLTS
9888 +    {"SC_PII_OSI_CLTS",        _SC_PII_OSI_CLTS},
9889 +#endif
9890 +#ifdef _SC_PII_OSI_COTS
9891 +    {"SC_PII_OSI_COTS",        _SC_PII_OSI_COTS},
9892 +#endif
9893 +#ifdef _SC_PII_OSI_M
9894 +    {"SC_PII_OSI_M",   _SC_PII_OSI_M},
9895 +#endif
9896 +#ifdef _SC_PII_SOCKET
9897 +    {"SC_PII_SOCKET",  _SC_PII_SOCKET},
9898 +#endif
9899 +#ifdef _SC_PII_XTI
9900 +    {"SC_PII_XTI",     _SC_PII_XTI},
9901 +#endif
9902 +#ifdef _SC_POLL
9903 +    {"SC_POLL",        _SC_POLL},
9904 +#endif
9905 +#ifdef _SC_PRIORITIZED_IO
9906 +    {"SC_PRIORITIZED_IO",      _SC_PRIORITIZED_IO},
9907 +#endif
9908 +#ifdef _SC_PRIORITY_SCHEDULING
9909 +    {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
9910 +#endif
9911 +#ifdef _SC_REALTIME_SIGNALS
9912 +    {"SC_REALTIME_SIGNALS",    _SC_REALTIME_SIGNALS},
9913 +#endif
9914 +#ifdef _SC_RE_DUP_MAX
9915 +    {"SC_RE_DUP_MAX",  _SC_RE_DUP_MAX},
9916 +#endif
9917 +#ifdef _SC_RTSIG_MAX
9918 +    {"SC_RTSIG_MAX",   _SC_RTSIG_MAX},
9919 +#endif
9920 +#ifdef _SC_SAVED_IDS
9921 +    {"SC_SAVED_IDS",   _SC_SAVED_IDS},
9922 +#endif
9923 +#ifdef _SC_SCHAR_MAX
9924 +    {"SC_SCHAR_MAX",   _SC_SCHAR_MAX},
9925 +#endif
9926 +#ifdef _SC_SCHAR_MIN
9927 +    {"SC_SCHAR_MIN",   _SC_SCHAR_MIN},
9928 +#endif
9929 +#ifdef _SC_SELECT
9930 +    {"SC_SELECT",      _SC_SELECT},
9931 +#endif
9932 +#ifdef _SC_SEMAPHORES
9933 +    {"SC_SEMAPHORES",  _SC_SEMAPHORES},
9934 +#endif
9935 +#ifdef _SC_SEM_NSEMS_MAX
9936 +    {"SC_SEM_NSEMS_MAX",       _SC_SEM_NSEMS_MAX},
9937 +#endif
9938 +#ifdef _SC_SEM_VALUE_MAX
9939 +    {"SC_SEM_VALUE_MAX",       _SC_SEM_VALUE_MAX},
9940 +#endif
9941 +#ifdef _SC_SHARED_MEMORY_OBJECTS
9942 +    {"SC_SHARED_MEMORY_OBJECTS",       _SC_SHARED_MEMORY_OBJECTS},
9943 +#endif
9944 +#ifdef _SC_SHRT_MAX
9945 +    {"SC_SHRT_MAX",    _SC_SHRT_MAX},
9946 +#endif
9947 +#ifdef _SC_SHRT_MIN
9948 +    {"SC_SHRT_MIN",    _SC_SHRT_MIN},
9949 +#endif
9950 +#ifdef _SC_SIGQUEUE_MAX
9951 +    {"SC_SIGQUEUE_MAX",        _SC_SIGQUEUE_MAX},
9952 +#endif
9953 +#ifdef _SC_SIGRT_MAX
9954 +    {"SC_SIGRT_MAX",   _SC_SIGRT_MAX},
9955 +#endif
9956 +#ifdef _SC_SIGRT_MIN
9957 +    {"SC_SIGRT_MIN",   _SC_SIGRT_MIN},
9958 +#endif
9959 +#ifdef _SC_SOFTPOWER
9960 +    {"SC_SOFTPOWER",   _SC_SOFTPOWER},
9961 +#endif
9962 +#ifdef _SC_SPLIT_CACHE
9963 +    {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
9964 +#endif
9965 +#ifdef _SC_SSIZE_MAX
9966 +    {"SC_SSIZE_MAX",   _SC_SSIZE_MAX},
9967 +#endif
9968 +#ifdef _SC_STACK_PROT
9969 +    {"SC_STACK_PROT",  _SC_STACK_PROT},
9970 +#endif
9971 +#ifdef _SC_STREAM_MAX
9972 +    {"SC_STREAM_MAX",  _SC_STREAM_MAX},
9973 +#endif
9974 +#ifdef _SC_SYNCHRONIZED_IO
9975 +    {"SC_SYNCHRONIZED_IO",     _SC_SYNCHRONIZED_IO},
9976 +#endif
9977 +#ifdef _SC_THREADS
9978 +    {"SC_THREADS",     _SC_THREADS},
9979 +#endif
9980 +#ifdef _SC_THREAD_ATTR_STACKADDR
9981 +    {"SC_THREAD_ATTR_STACKADDR",       _SC_THREAD_ATTR_STACKADDR},
9982 +#endif
9983 +#ifdef _SC_THREAD_ATTR_STACKSIZE
9984 +    {"SC_THREAD_ATTR_STACKSIZE",       _SC_THREAD_ATTR_STACKSIZE},
9985 +#endif
9986 +#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
9987 +    {"SC_THREAD_DESTRUCTOR_ITERATIONS",        _SC_THREAD_DESTRUCTOR_ITERATIONS},
9988 +#endif
9989 +#ifdef _SC_THREAD_KEYS_MAX
9990 +    {"SC_THREAD_KEYS_MAX",     _SC_THREAD_KEYS_MAX},
9991 +#endif
9992 +#ifdef _SC_THREAD_PRIORITY_SCHEDULING
9993 +    {"SC_THREAD_PRIORITY_SCHEDULING",  _SC_THREAD_PRIORITY_SCHEDULING},
9994 +#endif
9995 +#ifdef _SC_THREAD_PRIO_INHERIT
9996 +    {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
9997 +#endif
9998 +#ifdef _SC_THREAD_PRIO_PROTECT
9999 +    {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
10000 +#endif
10001 +#ifdef _SC_THREAD_PROCESS_SHARED
10002 +    {"SC_THREAD_PROCESS_SHARED",       _SC_THREAD_PROCESS_SHARED},
10003 +#endif
10004 +#ifdef _SC_THREAD_SAFE_FUNCTIONS
10005 +    {"SC_THREAD_SAFE_FUNCTIONS",       _SC_THREAD_SAFE_FUNCTIONS},
10006 +#endif
10007 +#ifdef _SC_THREAD_STACK_MIN
10008 +    {"SC_THREAD_STACK_MIN",    _SC_THREAD_STACK_MIN},
10009 +#endif
10010 +#ifdef _SC_THREAD_THREADS_MAX
10011 +    {"SC_THREAD_THREADS_MAX",  _SC_THREAD_THREADS_MAX},
10012 +#endif
10013 +#ifdef _SC_TIMERS
10014 +    {"SC_TIMERS",      _SC_TIMERS},
10015 +#endif
10016 +#ifdef _SC_TIMER_MAX
10017 +    {"SC_TIMER_MAX",   _SC_TIMER_MAX},
10018 +#endif
10019 +#ifdef _SC_TTY_NAME_MAX
10020 +    {"SC_TTY_NAME_MAX",        _SC_TTY_NAME_MAX},
10021 +#endif
10022 +#ifdef _SC_TZNAME_MAX
10023 +    {"SC_TZNAME_MAX",  _SC_TZNAME_MAX},
10024 +#endif
10025 +#ifdef _SC_T_IOV_MAX
10026 +    {"SC_T_IOV_MAX",   _SC_T_IOV_MAX},
10027 +#endif
10028 +#ifdef _SC_UCHAR_MAX
10029 +    {"SC_UCHAR_MAX",   _SC_UCHAR_MAX},
10030 +#endif
10031 +#ifdef _SC_UINT_MAX
10032 +    {"SC_UINT_MAX",    _SC_UINT_MAX},
10033 +#endif
10034 +#ifdef _SC_UIO_MAXIOV
10035 +    {"SC_UIO_MAXIOV",  _SC_UIO_MAXIOV},
10036 +#endif
10037 +#ifdef _SC_ULONG_MAX
10038 +    {"SC_ULONG_MAX",   _SC_ULONG_MAX},
10039 +#endif
10040 +#ifdef _SC_USHRT_MAX
10041 +    {"SC_USHRT_MAX",   _SC_USHRT_MAX},
10042 +#endif
10043 +#ifdef _SC_VERSION
10044 +    {"SC_VERSION",     _SC_VERSION},
10045 +#endif
10046 +#ifdef _SC_WORD_BIT
10047 +    {"SC_WORD_BIT",    _SC_WORD_BIT},
10048 +#endif
10049 +#ifdef _SC_XBS5_ILP32_OFF32
10050 +    {"SC_XBS5_ILP32_OFF32",    _SC_XBS5_ILP32_OFF32},
10051 +#endif
10052 +#ifdef _SC_XBS5_ILP32_OFFBIG
10053 +    {"SC_XBS5_ILP32_OFFBIG",   _SC_XBS5_ILP32_OFFBIG},
10054 +#endif
10055 +#ifdef _SC_XBS5_LP64_OFF64
10056 +    {"SC_XBS5_LP64_OFF64",     _SC_XBS5_LP64_OFF64},
10057 +#endif
10058 +#ifdef _SC_XBS5_LPBIG_OFFBIG
10059 +    {"SC_XBS5_LPBIG_OFFBIG",   _SC_XBS5_LPBIG_OFFBIG},
10060 +#endif
10061 +#ifdef _SC_XOPEN_CRYPT
10062 +    {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
10063 +#endif
10064 +#ifdef _SC_XOPEN_ENH_I18N
10065 +    {"SC_XOPEN_ENH_I18N",      _SC_XOPEN_ENH_I18N},
10066 +#endif
10067 +#ifdef _SC_XOPEN_LEGACY
10068 +    {"SC_XOPEN_LEGACY",        _SC_XOPEN_LEGACY},
10069 +#endif
10070 +#ifdef _SC_XOPEN_REALTIME
10071 +    {"SC_XOPEN_REALTIME",      _SC_XOPEN_REALTIME},
10072 +#endif
10073 +#ifdef _SC_XOPEN_REALTIME_THREADS
10074 +    {"SC_XOPEN_REALTIME_THREADS",      _SC_XOPEN_REALTIME_THREADS},
10075 +#endif
10076 +#ifdef _SC_XOPEN_SHM
10077 +    {"SC_XOPEN_SHM",   _SC_XOPEN_SHM},
10078 +#endif
10079 +#ifdef _SC_XOPEN_UNIX
10080 +    {"SC_XOPEN_UNIX",  _SC_XOPEN_UNIX},
10081 +#endif
10082 +#ifdef _SC_XOPEN_VERSION
10083 +    {"SC_XOPEN_VERSION",       _SC_XOPEN_VERSION},
10084 +#endif
10085 +#ifdef _SC_XOPEN_XCU_VERSION
10086 +    {"SC_XOPEN_XCU_VERSION",   _SC_XOPEN_XCU_VERSION},
10087 +#endif
10088 +#ifdef _SC_XOPEN_XPG2
10089 +    {"SC_XOPEN_XPG2",  _SC_XOPEN_XPG2},
10090 +#endif
10091 +#ifdef _SC_XOPEN_XPG3
10092 +    {"SC_XOPEN_XPG3",  _SC_XOPEN_XPG3},
10093 +#endif
10094 +#ifdef _SC_XOPEN_XPG4
10095 +    {"SC_XOPEN_XPG4",  _SC_XOPEN_XPG4},
10096 +#endif
10097 +};
10098 +
10099 +static int
10100 +conv_sysconf_confname(PyObject *arg, int *valuep)
10101 +{
10102 +    return conv_confname(arg, valuep, posix_constants_sysconf,
10103 +                         sizeof(posix_constants_sysconf)
10104 +                           / sizeof(struct constdef));
10105 +}
10106 +
10107 +PyDoc_STRVAR(posix_sysconf__doc__,
10108 +"sysconf(name) -> integer\n\n\
10109 +Return an integer-valued system configuration variable.");
10110 +
10111 +static PyObject *
10112 +posix_sysconf(PyObject *self, PyObject *args)
10113 +{
10114 +    PyObject *result = NULL;
10115 +    int name;
10116 +
10117 +    if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10118 +        int value;
10119 +
10120 +        errno = 0;
10121 +        value = sysconf(name);
10122 +        if (value == -1 && errno != 0)
10123 +            posix_error();
10124 +        else
10125 +            result = PyInt_FromLong(value);
10126 +    }
10127 +    return result;
10128 +}
10129 +#endif
10130 +
10131 +
10132 +/* This code is used to ensure that the tables of configuration value names
10133 + * are in sorted order as required by conv_confname(), and also to build the
10134 + * the exported dictionaries that are used to publish information about the
10135 + * names available on the host platform.
10136 + *
10137 + * Sorting the table at runtime ensures that the table is properly ordered
10138 + * when used, even for platforms we're not able to test on.  It also makes
10139 + * it easier to add additional entries to the tables.
10140 + */
10141 +
10142 +static int
10143 +cmp_constdefs(const void *v1,  const void *v2)
10144 +{
10145 +    const struct constdef *c1 =
10146 +        (const struct constdef *) v1;
10147 +    const struct constdef *c2 =
10148 +        (const struct constdef *) v2;
10149 +
10150 +    return strcmp(c1->name, c2->name);
10151 +}
10152 +
10153 +static int
10154 +setup_confname_table(struct constdef *table, size_t tablesize,
10155 +                    char *tablename, PyObject *module)
10156 +{
10157 +    PyObject *d = NULL;
10158 +    size_t i;
10159 +
10160 +    qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10161 +    d = PyDict_New();
10162 +    if (d == NULL)
10163 +           return -1;
10164 +
10165 +    for (i=0; i < tablesize; ++i) {
10166 +            PyObject *o = PyInt_FromLong(table[i].value);
10167 +            if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10168 +                   Py_XDECREF(o);
10169 +                   Py_DECREF(d);
10170 +                   return -1;
10171 +            }
10172 +           Py_DECREF(o);
10173 +    }
10174 +    return PyModule_AddObject(module, tablename, d);
10175 +}
10176 +
10177 +/* Return -1 on failure, 0 on success. */
10178 +static int
10179 +setup_confname_tables(PyObject *module)
10180 +{
10181 +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10182 +    if (setup_confname_table(posix_constants_pathconf,
10183 +                             sizeof(posix_constants_pathconf)
10184 +                               / sizeof(struct constdef),
10185 +                             "pathconf_names", module))
10186 +        return -1;
10187 +#endif
10188 +#ifdef HAVE_CONFSTR
10189 +    if (setup_confname_table(posix_constants_confstr,
10190 +                             sizeof(posix_constants_confstr)
10191 +                               / sizeof(struct constdef),
10192 +                             "confstr_names", module))
10193 +        return -1;
10194 +#endif
10195 +#ifdef HAVE_SYSCONF
10196 +    if (setup_confname_table(posix_constants_sysconf,
10197 +                             sizeof(posix_constants_sysconf)
10198 +                               / sizeof(struct constdef),
10199 +                             "sysconf_names", module))
10200 +        return -1;
10201 +#endif
10202 +    return 0;
10203 +}
10204 +
10205 +
10206 +PyDoc_STRVAR(posix_abort__doc__,
10207 +"abort() -> does not return!\n\n\
10208 +Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
10209 +in the hardest way possible on the hosting operating system.");
10210 +
10211 +static PyObject *
10212 +posix_abort(PyObject *self, PyObject *noargs)
10213 +{
10214 +    abort();
10215 +    /*NOTREACHED*/
10216 +    Py_FatalError("abort() called from Python code didn't abort!");
10217 +    return NULL;
10218 +}
10219 +
10220 +#ifdef MS_WINDOWS
10221 +PyDoc_STRVAR(win32_startfile__doc__,
10222 +"startfile(filepath [, operation]) - Start a file with its associated\n\
10223 +application.\n\
10224 +\n\
10225 +When \"operation\" is not specified or \"open\", this acts like\n\
10226 +double-clicking the file in Explorer, or giving the file name as an\n\
10227 +argument to the DOS \"start\" command: the file is opened with whatever\n\
10228 +application (if any) its extension is associated.\n\
10229 +When another \"operation\" is given, it specifies what should be done with\n\
10230 +the file.  A typical operation is \"print\".\n\
10231 +\n\
10232 +startfile returns as soon as the associated application is launched.\n\
10233 +There is no option to wait for the application to close, and no way\n\
10234 +to retrieve the application's exit status.\n\
10235 +\n\
10236 +The filepath is relative to the current directory.  If you want to use\n\
10237 +an absolute path, make sure the first character is not a slash (\"/\");\n\
10238 +the underlying Win32 ShellExecute function doesn't work if it is.");
10239 +
10240 +static PyObject *
10241 +win32_startfile(PyObject *self, PyObject *args)
10242 +{
10243 +       char *filepath;
10244 +       char *operation = NULL;
10245 +       HINSTANCE rc;
10246 +#ifdef Py_WIN_WIDE_FILENAMES
10247 +       if (unicode_file_names()) {
10248 +               PyObject *unipath, *woperation = NULL;
10249 +               if (!PyArg_ParseTuple(args, "U|s:startfile",
10250 +                                     &unipath, &operation)) {
10251 +                       PyErr_Clear();
10252 +                       goto normal;
10253 +               }
10254 +               
10255 +
10256 +               if (operation) {
10257 +                   woperation = PyUnicode_DecodeASCII(operation, 
10258 +                                                      strlen(operation), NULL);
10259 +                   if (!woperation) {
10260 +                           PyErr_Clear();
10261 +                           operation = NULL;
10262 +                           goto normal;
10263 +                   }
10264 +               }
10265 +                       
10266 +               Py_BEGIN_ALLOW_THREADS
10267 +               rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
10268 +                       PyUnicode_AS_UNICODE(unipath),
10269 +                       NULL, NULL, SW_SHOWNORMAL);
10270 +               Py_END_ALLOW_THREADS
10271 +
10272 +               Py_XDECREF(woperation);
10273 +               if (rc <= (HINSTANCE)32) {
10274 +                       PyObject *errval = win32_error_unicode("startfile",
10275 +                                               PyUnicode_AS_UNICODE(unipath));
10276 +                       return errval;
10277 +               }
10278 +               Py_INCREF(Py_None);
10279 +               return Py_None;
10280 +       }
10281 +#endif
10282 +
10283 +normal:
10284 +       if (!PyArg_ParseTuple(args, "et|s:startfile", 
10285 +                             Py_FileSystemDefaultEncoding, &filepath, 
10286 +                             &operation))
10287 +               return NULL;
10288 +       Py_BEGIN_ALLOW_THREADS
10289 +       rc = ShellExecute((HWND)0, operation, filepath, 
10290 +                         NULL, NULL, SW_SHOWNORMAL);
10291 +       Py_END_ALLOW_THREADS
10292 +       if (rc <= (HINSTANCE)32) {
10293 +               PyObject *errval = win32_error("startfile", filepath);
10294 +               PyMem_Free(filepath);
10295 +               return errval;
10296 +       }
10297 +       PyMem_Free(filepath);
10298 +       Py_INCREF(Py_None);
10299 +       return Py_None;
10300 +}
10301 +#endif
10302 +
10303 +#ifdef HAVE_GETLOADAVG
10304 +PyDoc_STRVAR(posix_getloadavg__doc__,
10305 +"getloadavg() -> (float, float, float)\n\n\
10306 +Return the number of processes in the system run queue averaged over\n\
10307 +the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10308 +was unobtainable");
10309 +
10310 +static PyObject *
10311 +posix_getloadavg(PyObject *self, PyObject *noargs)
10312 +{
10313 +    double loadavg[3];
10314 +    if (getloadavg(loadavg, 3)!=3) {
10315 +        PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10316 +        return NULL;
10317 +    } else
10318 +        return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
10319 +}
10320 +#endif
10321 +
10322 +#ifdef MS_WINDOWS
10323 +
10324 +PyDoc_STRVAR(win32_urandom__doc__,
10325 +"urandom(n) -> str\n\n\
10326 +Return a string of n random bytes suitable for cryptographic use.");
10327 +
10328 +typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
10329 +              LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
10330 +              DWORD dwFlags );
10331 +typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
10332 +              BYTE *pbBuffer );
10333 +
10334 +static CRYPTGENRANDOM pCryptGenRandom = NULL;
10335 +static HCRYPTPROV hCryptProv = 0;
10336 +
10337 +static PyObject*
10338 +win32_urandom(PyObject *self, PyObject *args)
10339 +{
10340 +       int howMany;
10341 +       PyObject* result;
10342 +
10343 +       /* Read arguments */
10344 +       if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10345 +               return NULL;
10346 +       if (howMany < 0)
10347 +               return PyErr_Format(PyExc_ValueError,
10348 +                                   "negative argument not allowed");
10349 +
10350 +       if (hCryptProv == 0) {
10351 +               HINSTANCE hAdvAPI32 = NULL;
10352 +               CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
10353 +
10354 +               /* Obtain handle to the DLL containing CryptoAPI
10355 +                  This should not fail */
10356 +               hAdvAPI32 = GetModuleHandle("advapi32.dll");
10357 +               if(hAdvAPI32 == NULL)
10358 +                       return win32_error("GetModuleHandle", NULL);
10359 +
10360 +               /* Obtain pointers to the CryptoAPI functions
10361 +                  This will fail on some early versions of Win95 */
10362 +               pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
10363 +                                               hAdvAPI32,
10364 +                                               "CryptAcquireContextA");
10365 +               if (pCryptAcquireContext == NULL)
10366 +                       return PyErr_Format(PyExc_NotImplementedError,
10367 +                                           "CryptAcquireContextA not found");
10368 +
10369 +               pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
10370 +                                               hAdvAPI32, "CryptGenRandom");
10371 +               if (pCryptGenRandom == NULL)
10372 +                       return PyErr_Format(PyExc_NotImplementedError,
10373 +                                           "CryptGenRandom not found");
10374 +
10375 +               /* Acquire context */
10376 +               if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
10377 +                                          PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
10378 +                       return win32_error("CryptAcquireContext", NULL);
10379 +       }
10380 +
10381 +       /* Allocate bytes */
10382 +       result = PyString_FromStringAndSize(NULL, howMany);
10383 +       if (result != NULL) {
10384 +               /* Get random data */
10385 +               if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
10386 +                                     PyString_AS_STRING(result))) {
10387 +                       Py_DECREF(result);
10388 +                       return win32_error("CryptGenRandom", NULL);
10389 +               }
10390 +       }
10391 +       return result;
10392 +}
10393 +#endif
10394 +
10395 +#ifdef __VMS
10396 +/* Use openssl random routine */
10397 +#include <openssl/rand.h>
10398 +PyDoc_STRVAR(vms_urandom__doc__,
10399 +"urandom(n) -> str\n\n\
10400 +Return a string of n random bytes suitable for cryptographic use.");
10401 +
10402 +static PyObject*
10403 +vms_urandom(PyObject *self, PyObject *args)
10404 +{
10405 +       int howMany;
10406 +       PyObject* result;
10407 +
10408 +       /* Read arguments */
10409 +       if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10410 +               return NULL;
10411 +       if (howMany < 0)
10412 +               return PyErr_Format(PyExc_ValueError,
10413 +                                   "negative argument not allowed");
10414 +
10415 +       /* Allocate bytes */
10416 +       result = PyString_FromStringAndSize(NULL, howMany);
10417 +       if (result != NULL) {
10418 +               /* Get random data */
10419 +               if (RAND_pseudo_bytes((unsigned char*)
10420 +                                     PyString_AS_STRING(result),
10421 +                                     howMany) < 0) {
10422 +                       Py_DECREF(result);
10423 +                       return PyErr_Format(PyExc_ValueError,
10424 +                                           "RAND_pseudo_bytes");
10425 +               }
10426 +       }
10427 +       return result;
10428 +}
10429 +#endif
10430 +
10431 +static PyMethodDef posix_methods[] = {
10432 +       {"access",      posix_access, METH_VARARGS, posix_access__doc__},
10433 +#ifdef HAVE_TTYNAME
10434 +       {"ttyname",     posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
10435 +#endif
10436 +       {"chdir",       posix_chdir, METH_VARARGS, posix_chdir__doc__},
10437 +       {"chmod",       posix_chmod, METH_VARARGS, posix_chmod__doc__},
10438 +#ifdef HAVE_CHOWN
10439 +       {"chown",       posix_chown, METH_VARARGS, posix_chown__doc__},
10440 +#endif /* HAVE_CHOWN */
10441 +#ifdef HAVE_LCHOWN
10442 +       {"lchown",      posix_lchown, METH_VARARGS, posix_lchown__doc__},
10443 +#endif /* HAVE_LCHOWN */
10444 +#ifdef HAVE_CHROOT
10445 +       {"chroot",      posix_chroot, METH_VARARGS, posix_chroot__doc__},
10446 +#endif
10447 +#ifdef HAVE_CTERMID
10448 +       {"ctermid",     posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
10449 +#endif
10450 +#ifdef HAVE_GETCWD
10451 +       {"getcwd",      posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
10452 +#ifdef Py_USING_UNICODE
10453 +       {"getcwdu",     posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
10454 +#endif
10455 +#endif
10456 +#ifdef HAVE_LINK
10457 +       {"link",        posix_link, METH_VARARGS, posix_link__doc__},
10458 +#endif /* HAVE_LINK */
10459 +       {"listdir",     posix_listdir, METH_VARARGS, posix_listdir__doc__},
10460 +       {"lstat",       posix_lstat, METH_VARARGS, posix_lstat__doc__},
10461 +       {"mkdir",       posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
10462 +#ifdef HAVE_NICE
10463 +       {"nice",        posix_nice, METH_VARARGS, posix_nice__doc__},
10464 +#endif /* HAVE_NICE */
10465 +#ifdef HAVE_READLINK
10466 +       {"readlink",    posix_readlink, METH_VARARGS, posix_readlink__doc__},
10467 +#endif /* HAVE_READLINK */
10468 +       {"rename",      posix_rename, METH_VARARGS, posix_rename__doc__},
10469 +       {"rmdir",       posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10470 +       {"stat",        posix_stat, METH_VARARGS, posix_stat__doc__},
10471 +       {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
10472 +#ifdef HAVE_SYMLINK
10473 +       {"symlink",     posix_symlink, METH_VARARGS, posix_symlink__doc__},
10474 +#endif /* HAVE_SYMLINK */
10475 +#ifdef HAVE_SYSTEM
10476 +       {"system",      posix_system, METH_VARARGS, posix_system__doc__},
10477 +#endif
10478 +       {"umask",       posix_umask, METH_VARARGS, posix_umask__doc__},
10479 +#ifdef HAVE_UNAME
10480 +       {"uname",       posix_uname, METH_NOARGS, posix_uname__doc__},
10481 +#endif /* HAVE_UNAME */
10482 +       {"unlink",      posix_unlink, METH_VARARGS, posix_unlink__doc__},
10483 +       {"remove",      posix_unlink, METH_VARARGS, posix_remove__doc__},
10484 +       {"utime",       posix_utime, METH_VARARGS, posix_utime__doc__},
10485 +#ifdef HAVE_TIMES
10486 +       {"times",       posix_times, METH_NOARGS, posix_times__doc__},
10487 +#endif /* HAVE_TIMES */
10488 +       {"_exit",       posix__exit, METH_VARARGS, posix__exit__doc__},
10489 +#ifdef HAVE_EXECV
10490 +       {"execv",       posix_execv, METH_VARARGS, posix_execv__doc__},
10491 +       {"execve",      posix_execve, METH_VARARGS, posix_execve__doc__},
10492 +#endif /* HAVE_EXECV */
10493 +#ifdef HAVE_SPAWNV
10494 +       {"spawnv",      posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10495 +       {"spawnve",     posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
10496 +#if defined(PYOS_OS2)
10497 +       {"spawnvp",     posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10498 +       {"spawnvpe",    posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
10499 +#endif /* PYOS_OS2 */
10500 +#endif /* HAVE_SPAWNV */
10501 +#ifdef HAVE_FORK1
10502 +       {"fork1",       posix_fork1, METH_NOARGS, posix_fork1__doc__},
10503 +#endif /* HAVE_FORK1 */
10504 +#ifdef HAVE_FORK
10505 +       {"fork",        posix_fork, METH_NOARGS, posix_fork__doc__},
10506 +#endif /* HAVE_FORK */
10507 +#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
10508 +       {"openpty",     posix_openpty, METH_NOARGS, posix_openpty__doc__},
10509 +#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
10510 +#ifdef HAVE_FORKPTY
10511 +       {"forkpty",     posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
10512 +#endif /* HAVE_FORKPTY */
10513 +#ifdef HAVE_GETEGID
10514 +       {"getegid",     posix_getegid, METH_NOARGS, posix_getegid__doc__},
10515 +#endif /* HAVE_GETEGID */
10516 +#ifdef HAVE_GETEUID
10517 +       {"geteuid",     posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
10518 +#endif /* HAVE_GETEUID */
10519 +#ifdef HAVE_GETGID
10520 +       {"getgid",      posix_getgid, METH_NOARGS, posix_getgid__doc__},
10521 +#endif /* HAVE_GETGID */
10522 +#ifdef HAVE_GETGROUPS
10523 +       {"getgroups",   posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
10524 +#endif
10525 +       {"getpid",      posix_getpid, METH_NOARGS, posix_getpid__doc__},
10526 +#ifdef HAVE_GETPGRP
10527 +       {"getpgrp",     posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
10528 +#endif /* HAVE_GETPGRP */
10529 +#ifdef HAVE_GETPPID
10530 +       {"getppid",     posix_getppid, METH_NOARGS, posix_getppid__doc__},
10531 +#endif /* HAVE_GETPPID */
10532 +#ifdef HAVE_GETUID
10533 +       {"getuid",      posix_getuid, METH_NOARGS, posix_getuid__doc__},
10534 +#endif /* HAVE_GETUID */
10535 +#ifdef HAVE_GETLOGIN
10536 +       {"getlogin",    posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
10537 +#endif
10538 +#ifdef HAVE_KILL
10539 +       {"kill",        posix_kill, METH_VARARGS, posix_kill__doc__},
10540 +#endif /* HAVE_KILL */
10541 +#ifdef HAVE_KILLPG
10542 +       {"killpg",      posix_killpg, METH_VARARGS, posix_killpg__doc__},
10543 +#endif /* HAVE_KILLPG */
10544 +#ifdef HAVE_PLOCK
10545 +       {"plock",       posix_plock, METH_VARARGS, posix_plock__doc__},
10546 +#endif /* HAVE_PLOCK */
10547 +#ifdef HAVE_POPEN
10548 +       {"popen",       posix_popen, METH_VARARGS, posix_popen__doc__},
10549 +#ifdef MS_WINDOWS
10550 +       {"popen2",      win32_popen2, METH_VARARGS},
10551 +       {"popen3",      win32_popen3, METH_VARARGS},
10552 +       {"popen4",      win32_popen4, METH_VARARGS},
10553 +       {"startfile",   win32_startfile, METH_VARARGS, win32_startfile__doc__},
10554 +#else
10555 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
10556 +       {"popen2",      os2emx_popen2, METH_VARARGS},
10557 +       {"popen3",      os2emx_popen3, METH_VARARGS},
10558 +       {"popen4",      os2emx_popen4, METH_VARARGS},
10559 +#endif
10560 +#endif
10561 +#endif /* HAVE_POPEN */
10562 +#ifdef HAVE_SETUID
10563 +       {"setuid",      posix_setuid, METH_VARARGS, posix_setuid__doc__},
10564 +#endif /* HAVE_SETUID */
10565 +#ifdef HAVE_SETEUID
10566 +       {"seteuid",     posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
10567 +#endif /* HAVE_SETEUID */
10568 +#ifdef HAVE_SETEGID
10569 +       {"setegid",     posix_setegid, METH_VARARGS, posix_setegid__doc__},
10570 +#endif /* HAVE_SETEGID */
10571 +#ifdef HAVE_SETREUID
10572 +       {"setreuid",    posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
10573 +#endif /* HAVE_SETREUID */
10574 +#ifdef HAVE_SETREGID
10575 +       {"setregid",    posix_setregid, METH_VARARGS, posix_setregid__doc__},
10576 +#endif /* HAVE_SETREGID */
10577 +#ifdef HAVE_SETGID
10578 +       {"setgid",      posix_setgid, METH_VARARGS, posix_setgid__doc__},
10579 +#endif /* HAVE_SETGID */
10580 +#ifdef HAVE_SETGROUPS
10581 +       {"setgroups",   posix_setgroups, METH_O, posix_setgroups__doc__},
10582 +#endif /* HAVE_SETGROUPS */
10583 +#ifdef HAVE_GETPGID
10584 +       {"getpgid",     posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
10585 +#endif /* HAVE_GETPGID */
10586 +#ifdef HAVE_SETPGRP
10587 +       {"setpgrp",     posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
10588 +#endif /* HAVE_SETPGRP */
10589 +#ifdef HAVE_WAIT
10590 +       {"wait",        posix_wait, METH_NOARGS, posix_wait__doc__},
10591 +#endif /* HAVE_WAIT */
10592 +#ifdef HAVE_WAIT3
10593 +        {"wait3",      posix_wait3, METH_VARARGS, posix_wait3__doc__},
10594 +#endif /* HAVE_WAIT3 */
10595 +#ifdef HAVE_WAIT4
10596 +        {"wait4",      posix_wait4, METH_VARARGS, posix_wait4__doc__},
10597 +#endif /* HAVE_WAIT4 */
10598 +#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
10599 +       {"waitpid",     posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
10600 +#endif /* HAVE_WAITPID */
10601 +#ifdef HAVE_GETSID
10602 +       {"getsid",      posix_getsid, METH_VARARGS, posix_getsid__doc__},
10603 +#endif /* HAVE_GETSID */
10604 +#ifdef HAVE_SETSID
10605 +       {"setsid",      posix_setsid, METH_NOARGS, posix_setsid__doc__},
10606 +#endif /* HAVE_SETSID */
10607 +#ifdef HAVE_SETPGID
10608 +       {"setpgid",     posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
10609 +#endif /* HAVE_SETPGID */
10610 +#ifdef HAVE_TCGETPGRP
10611 +       {"tcgetpgrp",   posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
10612 +#endif /* HAVE_TCGETPGRP */
10613 +#ifdef HAVE_TCSETPGRP
10614 +       {"tcsetpgrp",   posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
10615 +#endif /* HAVE_TCSETPGRP */
10616 +       {"open",        posix_open, METH_VARARGS, posix_open__doc__},
10617 +       {"close",       posix_close, METH_VARARGS, posix_close__doc__},
10618 +       {"dup",         posix_dup, METH_VARARGS, posix_dup__doc__},
10619 +       {"dup2",        posix_dup2, METH_VARARGS, posix_dup2__doc__},
10620 +       {"lseek",       posix_lseek, METH_VARARGS, posix_lseek__doc__},
10621 +       {"read",        posix_read, METH_VARARGS, posix_read__doc__},
10622 +       {"write",       posix_write, METH_VARARGS, posix_write__doc__},
10623 +       {"fstat",       posix_fstat, METH_VARARGS, posix_fstat__doc__},
10624 +       {"fdopen",      posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
10625 +       {"isatty",      posix_isatty, METH_VARARGS, posix_isatty__doc__},
10626 +#ifdef HAVE_PIPE
10627 +       {"pipe",        posix_pipe, METH_NOARGS, posix_pipe__doc__},
10628 +#endif
10629 +#ifdef HAVE_MKFIFO
10630 +       {"mkfifo",      posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
10631 +#endif
10632 +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10633 +       {"mknod",       posix_mknod, METH_VARARGS, posix_mknod__doc__},
10634 +#endif
10635 +#ifdef HAVE_DEVICE_MACROS
10636 +       {"major",       posix_major, METH_VARARGS, posix_major__doc__},
10637 +       {"minor",       posix_minor, METH_VARARGS, posix_minor__doc__},
10638 +       {"makedev",     posix_makedev, METH_VARARGS, posix_makedev__doc__},
10639 +#endif
10640 +#ifdef HAVE_FTRUNCATE
10641 +       {"ftruncate",   posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
10642 +#endif
10643 +#ifdef HAVE_PUTENV
10644 +       {"putenv",      posix_putenv, METH_VARARGS, posix_putenv__doc__},
10645 +#endif
10646 +#ifdef HAVE_UNSETENV
10647 +       {"unsetenv",    posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
10648 +#endif
10649 +#ifdef HAVE_STRERROR
10650 +       {"strerror",    posix_strerror, METH_VARARGS, posix_strerror__doc__},
10651 +#endif
10652 +#ifdef HAVE_FCHDIR
10653 +       {"fchdir",      posix_fchdir, METH_O, posix_fchdir__doc__},
10654 +#endif
10655 +#ifdef HAVE_FSYNC
10656 +       {"fsync",       posix_fsync, METH_O, posix_fsync__doc__},
10657 +#endif
10658 +#ifdef HAVE_FDATASYNC
10659 +       {"fdatasync",   posix_fdatasync,  METH_O, posix_fdatasync__doc__},
10660 +#endif
10661 +#ifdef HAVE_SYS_WAIT_H
10662 +#ifdef WCOREDUMP
10663 +        {"WCOREDUMP",  posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
10664 +#endif /* WCOREDUMP */
10665 +#ifdef WIFCONTINUED
10666 +        {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
10667 +#endif /* WIFCONTINUED */
10668 +#ifdef WIFSTOPPED
10669 +        {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
10670 +#endif /* WIFSTOPPED */
10671 +#ifdef WIFSIGNALED
10672 +        {"WIFSIGNALED",        posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
10673 +#endif /* WIFSIGNALED */
10674 +#ifdef WIFEXITED
10675 +        {"WIFEXITED",  posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
10676 +#endif /* WIFEXITED */
10677 +#ifdef WEXITSTATUS
10678 +        {"WEXITSTATUS",        posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
10679 +#endif /* WEXITSTATUS */
10680 +#ifdef WTERMSIG
10681 +        {"WTERMSIG",   posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
10682 +#endif /* WTERMSIG */
10683 +#ifdef WSTOPSIG
10684 +        {"WSTOPSIG",   posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
10685 +#endif /* WSTOPSIG */
10686 +#endif /* HAVE_SYS_WAIT_H */
10687 +#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
10688 +       {"fstatvfs",    posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
10689 +#endif
10690 +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
10691 +       {"statvfs",     posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
10692 +#endif
10693 +#ifdef HAVE_TMPFILE
10694 +       {"tmpfile",     posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
10695 +#endif
10696 +#ifdef HAVE_TEMPNAM
10697 +       {"tempnam",     posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
10698 +#endif
10699 +#ifdef HAVE_TMPNAM
10700 +       {"tmpnam",      posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
10701 +#endif
10702 +#ifdef HAVE_CONFSTR
10703 +       {"confstr",     posix_confstr, METH_VARARGS, posix_confstr__doc__},
10704 +#endif
10705 +#ifdef HAVE_SYSCONF
10706 +       {"sysconf",     posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
10707 +#endif
10708 +#ifdef HAVE_FPATHCONF
10709 +       {"fpathconf",   posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
10710 +#endif
10711 +#ifdef HAVE_PATHCONF
10712 +       {"pathconf",    posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
10713 +#endif
10714 +       {"abort",       posix_abort, METH_NOARGS, posix_abort__doc__},
10715 +#ifdef MS_WINDOWS
10716 +       {"_getfullpathname",    posix__getfullpathname, METH_VARARGS, NULL},
10717 +#endif
10718 +#ifdef HAVE_GETLOADAVG
10719 +       {"getloadavg",  posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
10720 +#endif
10721 + #ifdef MS_WINDOWS
10722 +       {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
10723 + #endif
10724 + #ifdef __VMS
10725 +       {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
10726 + #endif
10727 +       {NULL,          NULL}            /* Sentinel */
10728 +};
10729 +
10730 +
10731 +static int
10732 +ins(PyObject *module, char *symbol, long value)
10733 +{
10734 +        return PyModule_AddIntConstant(module, symbol, value);
10735 +}
10736 +
10737 +#if defined(PYOS_OS2)
10738 +/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
10739 +static int insertvalues(PyObject *module)
10740 +{
10741 +    APIRET    rc;
10742 +    ULONG     values[QSV_MAX+1];
10743 +    PyObject *v;
10744 +    char     *ver, tmp[50];
10745 +
10746 +    Py_BEGIN_ALLOW_THREADS
10747 +    rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
10748 +    Py_END_ALLOW_THREADS
10749 +
10750 +    if (rc != NO_ERROR) {
10751 +        os2_error(rc);
10752 +        return -1;
10753 +    }
10754 +
10755 +    if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
10756 +    if (ins(module, "memkernel",    values[QSV_TOTRESMEM])) return -1;
10757 +    if (ins(module, "memvirtual",   values[QSV_TOTAVAILMEM])) return -1;
10758 +    if (ins(module, "maxpathlen",   values[QSV_MAX_PATH_LENGTH])) return -1;
10759 +    if (ins(module, "maxnamelen",   values[QSV_MAX_COMP_LENGTH])) return -1;
10760 +    if (ins(module, "revision",     values[QSV_VERSION_REVISION])) return -1;
10761 +    if (ins(module, "timeslice",    values[QSV_MIN_SLICE])) return -1;
10762 +
10763 +    switch (values[QSV_VERSION_MINOR]) {
10764 +    case 0:  ver = "2.00"; break;
10765 +    case 10: ver = "2.10"; break;
10766 +    case 11: ver = "2.11"; break;
10767 +    case 30: ver = "3.00"; break;
10768 +    case 40: ver = "4.00"; break;
10769 +    case 50: ver = "5.00"; break;
10770 +    default:
10771 +        PyOS_snprintf(tmp, sizeof(tmp),
10772 +                     "%d-%d", values[QSV_VERSION_MAJOR],
10773 +                      values[QSV_VERSION_MINOR]);
10774 +        ver = &tmp[0];
10775 +    }
10776 +
10777 +    /* Add Indicator of the Version of the Operating System */
10778 +    if (PyModule_AddStringConstant(module, "version", tmp) < 0)
10779 +        return -1;
10780 +
10781 +    /* Add Indicator of Which Drive was Used to Boot the System */
10782 +    tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
10783 +    tmp[1] = ':';
10784 +    tmp[2] = '\0';
10785 +
10786 +    return PyModule_AddStringConstant(module, "bootdrive", tmp);
10787 +}
10788 +#endif
10789 +
10790 +static int
10791 +all_ins(PyObject *d)
10792 +{
10793 +#ifdef F_OK
10794 +        if (ins(d, "F_OK", (long)F_OK)) return -1;
10795 +#endif
10796 +#ifdef R_OK
10797 +        if (ins(d, "R_OK", (long)R_OK)) return -1;
10798 +#endif
10799 +#ifdef W_OK
10800 +        if (ins(d, "W_OK", (long)W_OK)) return -1;
10801 +#endif
10802 +#ifdef X_OK
10803 +        if (ins(d, "X_OK", (long)X_OK)) return -1;
10804 +#endif
10805 +#ifdef NGROUPS_MAX
10806 +        if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
10807 +#endif
10808 +#ifdef TMP_MAX
10809 +        if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
10810 +#endif
10811 +#ifdef WCONTINUED
10812 +        if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
10813 +#endif
10814 +#ifdef WNOHANG
10815 +        if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
10816 +#endif
10817 +#ifdef WUNTRACED
10818 +        if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
10819 +#endif
10820 +#ifdef O_RDONLY
10821 +        if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
10822 +#endif
10823 +#ifdef O_WRONLY
10824 +        if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
10825 +#endif
10826 +#ifdef O_RDWR
10827 +        if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
10828 +#endif
10829 +#ifdef O_NDELAY
10830 +        if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
10831 +#endif
10832 +#ifdef O_NONBLOCK
10833 +        if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
10834 +#endif
10835 +#ifdef O_APPEND
10836 +        if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
10837 +#endif
10838 +#ifdef O_DSYNC
10839 +        if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
10840 +#endif
10841 +#ifdef O_RSYNC
10842 +        if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
10843 +#endif
10844 +#ifdef O_SYNC
10845 +        if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
10846 +#endif
10847 +#ifdef O_NOCTTY
10848 +        if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
10849 +#endif
10850 +#ifdef O_CREAT
10851 +        if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
10852 +#endif
10853 +#ifdef O_EXCL
10854 +        if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
10855 +#endif
10856 +#ifdef O_TRUNC
10857 +        if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
10858 +#endif
10859 +#ifdef O_BINARY
10860 +        if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
10861 +#endif
10862 +#ifdef O_TEXT
10863 +        if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
10864 +#endif
10865 +#ifdef O_LARGEFILE
10866 +        if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
10867 +#endif
10868 +#ifdef O_SHLOCK
10869 +        if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
10870 +#endif
10871 +#ifdef O_EXLOCK
10872 +        if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
10873 +#endif
10874 +
10875 +/* MS Windows */
10876 +#ifdef O_NOINHERIT
10877 +       /* Don't inherit in child processes. */
10878 +        if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
10879 +#endif
10880 +#ifdef _O_SHORT_LIVED
10881 +       /* Optimize for short life (keep in memory). */
10882 +       /* MS forgot to define this one with a non-underscore form too. */
10883 +        if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
10884 +#endif
10885 +#ifdef O_TEMPORARY
10886 +       /* Automatically delete when last handle is closed. */
10887 +        if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
10888 +#endif
10889 +#ifdef O_RANDOM
10890 +       /* Optimize for random access. */
10891 +        if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
10892 +#endif
10893 +#ifdef O_SEQUENTIAL
10894 +       /* Optimize for sequential access. */
10895 +        if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
10896 +#endif
10897 +
10898 +/* GNU extensions. */
10899 +#ifdef O_DIRECT
10900 +        /* Direct disk access. */
10901 +        if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
10902 +#endif
10903 +#ifdef O_DIRECTORY
10904 +        /* Must be a directory.         */
10905 +        if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
10906 +#endif
10907 +#ifdef O_NOFOLLOW
10908 +        /* Do not follow links.         */
10909 +        if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
10910 +#endif
10911 +
10912 +       /* These come from sysexits.h */
10913 +#ifdef EX_OK
10914 +       if (ins(d, "EX_OK", (long)EX_OK)) return -1;
10915 +#endif /* EX_OK */
10916 +#ifdef EX_USAGE
10917 +       if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
10918 +#endif /* EX_USAGE */
10919 +#ifdef EX_DATAERR
10920 +       if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
10921 +#endif /* EX_DATAERR */
10922 +#ifdef EX_NOINPUT
10923 +       if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
10924 +#endif /* EX_NOINPUT */
10925 +#ifdef EX_NOUSER
10926 +       if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
10927 +#endif /* EX_NOUSER */
10928 +#ifdef EX_NOHOST
10929 +       if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
10930 +#endif /* EX_NOHOST */
10931 +#ifdef EX_UNAVAILABLE
10932 +       if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
10933 +#endif /* EX_UNAVAILABLE */
10934 +#ifdef EX_SOFTWARE
10935 +       if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
10936 +#endif /* EX_SOFTWARE */
10937 +#ifdef EX_OSERR
10938 +       if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
10939 +#endif /* EX_OSERR */
10940 +#ifdef EX_OSFILE
10941 +       if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
10942 +#endif /* EX_OSFILE */
10943 +#ifdef EX_CANTCREAT
10944 +       if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
10945 +#endif /* EX_CANTCREAT */
10946 +#ifdef EX_IOERR
10947 +       if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
10948 +#endif /* EX_IOERR */
10949 +#ifdef EX_TEMPFAIL
10950 +       if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
10951 +#endif /* EX_TEMPFAIL */
10952 +#ifdef EX_PROTOCOL
10953 +       if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
10954 +#endif /* EX_PROTOCOL */
10955 +#ifdef EX_NOPERM
10956 +       if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
10957 +#endif /* EX_NOPERM */
10958 +#ifdef EX_CONFIG
10959 +       if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
10960 +#endif /* EX_CONFIG */
10961 +#ifdef EX_NOTFOUND
10962 +       if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
10963 +#endif /* EX_NOTFOUND */
10964 +
10965 +#ifdef HAVE_SPAWNV
10966 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
10967 +       if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
10968 +       if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
10969 +       if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
10970 +       if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
10971 +       if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
10972 +       if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
10973 +       if (ins(d, "P_PM", (long)P_PM)) return -1;
10974 +       if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
10975 +       if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
10976 +       if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
10977 +       if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
10978 +       if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
10979 +       if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
10980 +       if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
10981 +       if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
10982 +       if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
10983 +       if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
10984 +       if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
10985 +       if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
10986 +       if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
10987 +#else
10988 +        if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
10989 +        if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
10990 +        if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
10991 +        if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
10992 +        if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
10993 +#endif
10994 +#endif
10995 +
10996 +#if defined(PYOS_OS2)
10997 +        if (insertvalues(d)) return -1;
10998 +#endif
10999 +        return 0;
11000 +}
11001 +
11002 +
11003 +#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
11004 +#define INITFUNC initnt
11005 +#define MODNAME "nt"
11006 +
11007 +#elif defined(PYOS_OS2)
11008 +#define INITFUNC initos2
11009 +#define MODNAME "os2"
11010 +
11011 +#else
11012 +#define INITFUNC initposix
11013 +#define MODNAME "posix"
11014 +#endif
11015 +
11016 +PyMODINIT_FUNC
11017 +INITFUNC(void)
11018 +{
11019 +       PyObject *m, *v;
11020 +
11021 +       m = Py_InitModule3(MODNAME,
11022 +                          posix_methods,
11023 +                          posix__doc__);
11024 +       if (m == NULL)
11025 +               return;
11026 +
11027 +       /* Initialize environ dictionary */
11028 +       v = convertenviron();
11029 +       Py_XINCREF(v);
11030 +       if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11031 +               return;
11032 +       Py_DECREF(v);
11033 +
11034 +        if (all_ins(m))
11035 +                return;
11036 +
11037 +        if (setup_confname_tables(m))
11038 +                return;
11039 +
11040 +       Py_INCREF(PyExc_OSError);
11041 +       PyModule_AddObject(m, "error", PyExc_OSError);
11042 +
11043 +#ifdef HAVE_PUTENV
11044 +       if (posix_putenv_garbage == NULL)
11045 +               posix_putenv_garbage = PyDict_New();
11046 +#endif
11047 +
11048 +       if (!initialized) {
11049 +               stat_result_desc.name = MODNAME ".stat_result";
11050 +               stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11051 +               stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11052 +               stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11053 +               PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11054 +               structseq_new = StatResultType.tp_new;
11055 +               StatResultType.tp_new = statresult_new;
11056 +
11057 +               statvfs_result_desc.name = MODNAME ".statvfs_result";
11058 +               PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
11059 +       }
11060 +       Py_INCREF((PyObject*) &StatResultType);
11061 +       PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11062 +       Py_INCREF((PyObject*) &StatVFSResultType);
11063 +       PyModule_AddObject(m, "statvfs_result",
11064 +                          (PyObject*) &StatVFSResultType);
11065 +       initialized = 1;
11066 +
11067 +#ifdef __APPLE__
11068 +       /*
11069 +        * Step 2 of weak-linking support on Mac OS X.
11070 +        *
11071 +        * The code below removes functions that are not available on the
11072 +        * currently active platform. 
11073 +        *
11074 +        * This block allow one to use a python binary that was build on
11075 +        * OSX 10.4 on OSX 10.3, without loosing access to new APIs on 
11076 +        * OSX 10.4.
11077 +        */
11078 +#ifdef HAVE_FSTATVFS
11079 +       if (fstatvfs == NULL) {
11080 +               if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11081 +                       return;
11082 +               }
11083 +       }
11084 +#endif /* HAVE_FSTATVFS */
11085 +
11086 +#ifdef HAVE_STATVFS
11087 +       if (statvfs == NULL) {
11088 +               if (PyObject_DelAttrString(m, "statvfs") == -1) {
11089 +                       return;
11090 +               }
11091 +       }
11092 +#endif /* HAVE_STATVFS */
11093 +
11094 +# ifdef HAVE_LCHOWN
11095 +       if (lchown == NULL) {
11096 +               if (PyObject_DelAttrString(m, "lchown") == -1) {
11097 +                       return;
11098 +               }
11099 +       }
11100 +#endif /* HAVE_LCHOWN */
11101 +
11102 +
11103 +#endif /* __APPLE__ */
11104 +
11105 +}
11106 +
11107 +#ifdef __cplusplus
11108 +}
11109 +#endif
11110 +
11111 +