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
5 AC_CONFIG_SRCDIR([Include/object.h])
6 AC_CONFIG_HEADER(pyconfig.h)
8 +# Find compiler while respecting --host setting.
10 +AC_CHECK_TOOLS(CC,gcc cc)
11 +AC_CHECK_TOOLS(CXX,g++ c++)
13 dnl This is for stuff that absolutely must end up in pyconfig.h.
14 dnl Please use pyport.h instead, if possible.
17 AC_MSG_CHECKING(MACHDEP)
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
26 ac_sys_release=`uname -r`
29 + m=`$CC -dumpmachine`
30 + changequote(<<, >>)#dnl
31 + ac_sys_system=`expr "$m" : "[^-]*-\([^-]*\)"`
32 + changequote([, ])#dnl
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 `;;
43 ac_md_system=`echo $ac_sys_system |
44 tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'`
45 ac_md_release=`echo $ac_sys_release |
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"
59 +# The executable extension on the host.
61 AC_MSG_CHECKING(for --with-suffix)
65 rmdir CaseSensitiveTestDir
67 +# The .o/.obj extension on the host.
76 AC_CHECK_PROGS(AR, ar aal, ar)
77 +AC_CHECK_TOOL(RANLIB,ranlib)
78 +AC_CHECK_TOOLS(AR,ar aal,ar)
81 AC_CHECK_PROG(SVNVERSION, svnversion, found, not-found)
82 @@ -3369,27 +3396,15 @@
86 -AC_MSG_CHECKING(for /dev/ptmx)
91 - AC_DEFINE(HAVE_DEV_PTMX, 1,
92 - [Define if we have /dev/ptmx.])
97 -AC_MSG_CHECKING(for /dev/ptc)
102 - AC_DEFINE(HAVE_DEV_PTC, 1,
103 - [Define if we have /dev/ptc.])
107 +AC_CHECK_FILE(/dev/ptmx,
108 + [AC_DEFINE(HAVE_DEV_PTMX, 1,
109 + [Define if we have /dev/ptmx.])],
112 +AC_CHECK_FILE(/dev/ptc,
113 + [AC_DEFINE(HAVE_DEV_PTC, 1,
114 + [Define if we have /dev/ptc.])],
119 @@ -3411,7 +3426,8 @@
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>
129 @@ -3447,7 +3463,7 @@
132 AC_DEFINE(PY_FORMAT_SIZE_T, "z", [Define to printf format modifier for Py_ssize_t])],
134 + AC_MSG_RESULT(no)))
136 AC_CHECK_TYPE(socklen_t,,
137 AC_DEFINE(socklen_t,int,
138 @@ -3477,6 +3493,53 @@
143 +AC_SUBST(cross_compiling)
145 +if test "$cross_compiling" = "yes"; then
146 + AC_MSG_CHECKING(cc for build)
147 + CC_FOR_BUILD="${CC_FOR_BUILD-cc}"
149 + CC_FOR_BUILD="${CC_FOR_BUILD-$CC}"
152 +if test "$cross_compiling" = "yes"; then
153 + AC_MSG_RESULT($CC_FOR_BUILD)
156 +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler (default: cc)])
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`
163 + PYTHON_FOR_BUILD='./$(BUILDPYTHON)'
166 +if test "$cross_compiling" = "yes"; then
167 + AC_MSG_RESULT($PYTHON_FOR_BUILD)
169 +AC_ARG_VAR(PYTHON_FOR_BUILD,[build system python (default: python)])
170 +AC_SUBST(PYTHON_FOR_BUILD)
172 +if test "$cross_compiling" = "yes"; then
173 + CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-}
174 + CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD- -I.}
176 + LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-}
178 + RUNSHARED="MACHDEP=$ac_sys_system SRCDIR=$srcdir SO=${SO}"
181 + O_FOR_BUILD=$(OBJEXT)
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)
189 # generate output files
190 AC_CONFIG_FILES(Makefile.pre Modules/Setup.config)
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
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
208 + if os.environ.get('CROSS_COMPILING') == 'yes':
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
217 +"""distutils.command.build_ext
219 +Implements the Distutils 'build_ext' command, for building extension
220 +modules (currently limited to C extensions, should accommodate C++
221 +extensions ASAP)."""
223 +# This module should be kept compatible with Python 2.1.
225 +__revision__ = "$Id: build_ext.py 54942 2007-04-24 15:27:25Z georg.brandl $"
227 +import sys, os, string, re
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
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]*)*$')
242 +def show_compilers ():
243 + from distutils.ccompiler import show_compilers
247 +class build_ext (Command):
249 + description = "build C/C++ extensions (compile/link to build directory)"
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
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())
269 + sep_by = " (separated by '%s')" % os.pathsep
271 + ('build-lib=', 'b',
272 + "directory for compiled extension modules"),
273 + ('build-temp=', 't',
274 + "directory for temporary files (build by-products)"),
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),
281 + "C preprocessor macros to define"),
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),
289 + "directories to search for shared C libraries at runtime"),
290 + ('link-objects=', 'O',
291 + "extra explicit link objects to include in the link"),
293 + "compile/link with debugging information"),
295 + "forcibly build everything (ignore file timestamps)"),
297 + "specify the compiler type"),
299 + "make SWIG create C++ files (default is C)"),
300 + ('swig-opts=', None,
301 + "list of SWIG command line options"),
303 + "path to the SWIG executable"),
306 + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp']
309 + ('help-compiler', None,
310 + "list available compilers", show_compilers),
313 + def initialize_options (self):
314 + self.extensions = None
315 + self.build_lib = None
316 + self.build_temp = None
318 + self.package = None
320 + self.include_dirs = None
323 + self.libraries = None
324 + self.library_dirs = None
326 + self.link_objects = None
329 + self.compiler = None
331 + self.swig_cpp = None
332 + self.swig_opts = None
334 + def finalize_options (self):
335 + from distutils import sysconfig
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'))
344 + if self.package is None:
345 + self.package = self.distribution.ext_package
347 + self.extensions = self.distribution.ext_modules
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)
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)
365 + if type(self.libraries) is StringType:
366 + self.libraries = [self.libraries]
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)
377 + if self.rpath is None:
379 + elif type(self.rpath) is StringType:
380 + self.rpath = string.split(self.rpath, os.pathsep)
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'))
388 + self.build_temp = os.path.join(self.build_temp, "Debug")
390 + self.build_temp = os.path.join(self.build_temp, "Release")
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'))
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'))
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(),
411 + # building python standard extensions
412 + self.library_dirs.append('.')
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'))
422 + # building python standard extensions
423 + self.library_dirs.append('.')
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.
431 + defines = string.split(self.define, ',')
432 + self.define = map(lambda symbol: (symbol, '1'), defines)
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.
438 + self.undef = string.split(self.undef, ',')
440 + if self.swig_opts is None:
441 + self.swig_opts = []
443 + self.swig_opts = self.swig_opts.split(' ')
445 + # finalize_options ()
450 + from distutils.ccompiler import new_compiler
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.
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.
464 + if not self.extensions:
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)
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,
481 + customize_compiler(self.compiler)
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)
505 + # Now actually compile and link everything.
506 + self.build_extensions()
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.
518 + Raise DistutilsSetupError if the structure is invalid anywhere;
519 + just returns otherwise.
521 + if type(extensions) is not ListType:
522 + raise DistutilsSetupError, \
523 + "'ext_modules' option must be a list of Extension instances"
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)
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")
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)")
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)")
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'])
555 + # Easy stuff: one-to-one mapping from dict elements to
556 + # instance attributes.
557 + for key in ('include_dirs',
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)
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")
573 + # Non-trivial stuff: 'macros' split into 'define_macros'
574 + # and 'undef_macros'.
575 + macros = build_info.get('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)
590 + extensions[i] = ext
594 + # check_extensions_list ()
597 + def get_source_files (self):
598 + self.check_extensions_list(self.extensions)
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)
608 + def get_outputs (self):
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)
615 + # And build the list of output (built) filenames. Note that this
616 + # ignores the 'inplace' flag, and assumes everything goes in the
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)))
627 + def build_extensions(self):
628 + # First, sanity-check the 'extensions' list
629 + self.check_extensions_list(self.extensions)
631 + for ext in self.extensions:
632 + self.build_extension(ext)
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)
643 + fullname = self.get_ext_fullname(ext.name)
645 + # ignore build-lib -- put the compiled extension into
646 + # the source tree along with pure Python modules
648 + modpath = string.split(fullname, '.')
649 + package = string.join(modpath[0:-1], '.')
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))
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)
664 + log.info("building '%s' extension", ext.name)
666 + # First, scan the sources for SWIG definition files (.i), run
667 + # SWIG on 'em to create .c files, and modify the sources list
669 + sources = self.swig_sources(sources, ext)
671 + # Next, compile the source code to object files.
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!
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 []
687 + macros = ext.define_macros[:]
688 + for undef in ext.undef_macros:
689 + macros.append((undef,))
691 + objects = self.compiler.compile(sources,
692 + output_dir=self.build_temp,
694 + include_dirs=ext.include_dirs,
696 + extra_postargs=extra_args,
697 + depends=ext.depends)
699 + # XXX -- this is a Vile HACK!
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.
708 + self._built_objects = objects[:]
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 []
717 + # Detect target language, if not provided
718 + language = ext.language or self.compiler.detect_language(sources)
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),
728 + build_temp=self.build_temp,
729 + target_lang=language)
732 + def swig_sources (self, sources, extension):
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.
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
750 + log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
752 + if self.swig_cpp or ('-c++' in self.swig_opts) or \
753 + ('-c++' in extension.swig_opts):
754 + target_ext = '.cpp'
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]
765 + new_sources.append(source)
767 + if not swig_sources:
770 + swig = self.swig or self.find_swig()
771 + swig_cmd = [swig, "-python"]
772 + swig_cmd.extend(self.swig_opts)
774 + swig_cmd.append("-c++")
776 + # Do not override commandline arguments
777 + if not self.swig_opts:
778 + for o in extension.swig_opts:
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])
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
796 + if os.name == "posix":
798 + elif os.name == "nt":
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):
810 + elif os.name == "os2":
811 + # assume swig available in the PATH.
815 + raise DistutilsPlatformError, \
816 + ("I don't know how to find (much less run) SWIG "
817 + "on platform '%s'") % os.name
821 + # -- Name generators -----------------------------------------------
822 + # (extension names, filenames, whatever)
824 + def get_ext_fullname (self, ext_name):
825 + if self.package is None:
828 + return self.package + '.' + ext_name
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
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
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.
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
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).
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"
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]
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
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
905 + template = "python%d.%d"
906 + pythonlib = (template %
907 + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
908 + # Get SHLIBS from Makefile
910 + for lib in sysconfig.get_config_var('SHLIBS').split():
911 + if lib.startswith('-l'):
912 + extra.append(lib[2:])
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
919 + elif sys.platform == 'darwin':
920 + # Don't use the default code below
921 + return ext.libraries
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]
931 + return ext.libraries
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
946 # C flags used for building the interpreter object files
947 PY_CFLAGS= $(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
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@
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@
960 +PYTHON_FOR_BUILD= @PYTHON_FOR_BUILD@
962 # Machine-dependent subdirectories
964 @@ -201,26 +214,28 @@
965 PGEN= Parser/pgen$(EXE)
969 - Parser/grammar1.o \
970 - Parser/listnode.o \
973 - Parser/parsetok.o \
975 - Parser/metagrammar.o \
976 - Parser/firstsets.o \
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)
993 +PARSER_OBJS= $(POBJS) \
994 + Parser/myreadline.$(O_FOR_BUILD) \
995 + Parser/tokenizer.$(O_FOR_BUILD)
998 - Objects/obmalloc.o \
999 - Python/mysnprintf.o \
1000 - Parser/tokenizer_pgen.o \
1001 - Parser/printgrammar.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)
1009 PGENOBJS= $(PGENMAIN) $(POBJS) $(PGOBJS)
1011 @@ -341,15 +356,15 @@
1013 $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
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
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;; \
1031 # Build static library
1033 -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
1035 $(PGEN): $(PGENOBJS)
1036 - $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
1037 + $(CC_FOR_BUILD) $(OPT) $(LDFLAGS_FOR_BUILD) $(PGENOBJS) $(LIBS) -o $(PGEN)
1039 Parser/grammar.o: $(srcdir)/Parser/grammar.c \
1040 $(srcdir)/Include/token.h \
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
1048 -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1049 -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
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
1058 # Like testall, but with a single pass only
1060 distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
1061 setuptools setuptools/command setuptools/tests setuptools.egg-info \
1063 -libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR)
1064 +libinstall: $(PYTHON_FOR_BUILD) $(srcdir)/Lib/$(PLATDIR)
1065 @for i in $(SCRIPTDIR) $(LIBDEST); \
1067 if test ! -d $(DESTDIR)$$i; then \
1068 @@ -782,19 +797,19 @@
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 \
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 \
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
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
1100 # Install the include files
1102 # Install the dynamically loadable modules
1103 # This goes into $(exec_prefix)
1105 - $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
1106 + CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' CROSS_COMPILING='$(CROSS
1108 + $(RUNSHARED) ./$(PYTHON_FOR_BUILD) -E $(srcdir)/setup.py install \
1109 --prefix=$(prefix) \
1110 --install-scripts=$(BINDIR) \
1111 --install-platlib=$(DESTSHARED) \
1114 # This installs a few of the useful scripts in Tools/scripts
1116 - SRCDIR=$(srcdir) $(RUNSHARED) \
1117 - ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
1119 + $(PYTHON_FOR_BUILD) $(srcdir)/Tools/scripts/setup.py install \
1120 --prefix=$(prefix) \
1121 --install-scripts=$(BINDIR) \
1123 @@ -988,6 +1005,11 @@
1125 $(CC) -c $(PY_CFLAGS) -o $@ $<
1127 +# '.x' is the native object format during cross-compile.
1129 + $(CC_FOR_BUILD) -c $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o $@ $<
1132 # Run reindent on the library
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
1139 +# Top-level Makefile for Python
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:
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.
1157 +# See also the section "Build instructions" in the README file.
1159 +# === Variables set by makesetup ===
1164 +# === Variables set by configure
1175 +SVNVERSION= @SVNVERSION@
1177 +# Shell used by make (some versions default to the login shell, which is bad)
1180 +# Use this to make a link between python$(VERSION) and python in $(BINDIR)
1183 +# Portable install script (configure doesn't always guess right)
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
1193 +MAKESETUP= $(srcdir)/Modules/makesetup
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@
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
1214 +# Machine-dependent subdirectories
1217 +# Install prefix for architecture-independent files
1220 +# Install prefix for architecture-dependent files
1221 +exec_prefix= @exec_prefix@
1223 +# Install prefix for data files
1224 +datarootdir= @datarootdir@
1226 +# Expanded directories
1227 +BINDIR= $(exec_prefix)/bin
1228 +LIBDIR= $(exec_prefix)/lib64
1230 +INCLUDEDIR= @includedir@
1231 +CONFINCLUDEDIR= $(exec_prefix)/include
1232 +SCRIPTDIR= $(prefix)/lib64
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)
1241 +# Symbols used for using shared libraries
1243 +LDSHARED= @LDSHARED@
1244 +BLDSHARED= @BLDSHARED@
1245 +DESTSHARED= $(BINLIBDEST)/lib-dynload
1247 +# Executable suffix (.exe on Windows and Mac OS X)
1249 +BUILDEXE= @BUILDEXEEXT@
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
1263 +# Options to enable prebinding (for fast startup prior to Mac OS X 10.3)
1264 +OTHER_LIBTOOL_OPT=@OTHER_LIBTOOL_OPT@
1266 +# Environment to run shared python without installed libraries
1267 +RUNSHARED= @RUNSHARED@
1269 +# Modes for directories, executables and data files created by the
1270 +# install process. Default to user-only-writable for all file types.
1275 +# configure script arguments
1276 +CONFIG_ARGS= @CONFIG_ARGS@
1279 +# Subdirectories with code
1282 +# Other subdirectories
1283 +SUBDIRSTOO= Include Lib Misc Demo
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)
1293 +LDLIBRARY= @LDLIBRARY@
1294 +BLDLIBRARY= @BLDLIBRARY@
1295 +DLLLIBRARY= @DLLLIBRARY@
1296 +LDLIBRARYDIR= @LDLIBRARYDIR@
1297 +INSTSONAME= @INSTSONAME@
1303 +SYSLIBS= $(LIBM) $(LIBC)
1306 +THREADOBJ= @THREADOBJ@
1307 +DLINCLDIR= @DLINCLDIR@
1308 +DYNLOADFILE= @DYNLOADFILE@
1309 +MACHDEP_OBJS= @MACHDEP_OBJS@
1310 +UNICODE_OBJS= @UNICODE_OBJS@
1312 +PYTHON= python$(EXE)
1313 +BUILDPYTHON= python$(BUILDEXE)
1315 +# === Definitions added by makesetup ===
1318 +##########################################################################
1321 + Modules/config.o \
1322 + Modules/getpath.o \
1324 + Modules/gcmodule.o
1326 +# Used of signalmodule.o is not available
1327 +SIGNAL_OBJS= @SIGNAL_OBJS@
1330 +##########################################################################
1332 +GRAMMAR_H= $(srcdir)/Include/graminit.h
1333 +GRAMMAR_C= $(srcdir)/Python/graminit.c
1334 +GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar
1337 +##########################################################################
1339 +PGEN= Parser/pgen$(EXE)
1342 + Parser/acceler.o \
1343 + Parser/grammar1.o \
1344 + Parser/listnode.o \
1347 + Parser/parsetok.o \
1349 + Parser/metagrammar.o \
1350 + Parser/firstsets.o \
1351 + Parser/grammar.o \
1354 +PARSER_OBJS= $(POBJS) Parser/myreadline.o Parser/tokenizer.o
1357 + Objects/obmalloc.o \
1358 + Python/mysnprintf.o \
1359 + Parser/tokenizer_pgen.o \
1360 + Parser/printgrammar.o \
1363 +PGENOBJS= $(PGENMAIN) $(POBJS) $(PGOBJS)
1365 +##########################################################################
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
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
1377 +##########################################################################
1380 + Python/Python-ast.o \
1383 + Python/bltinmodule.o \
1385 + Python/compile.o \
1389 + Python/frozenmain.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 \
1399 + Python/importdl.o \
1400 + Python/marshal.o \
1401 + Python/modsupport.o \
1402 + Python/mystrtoul.o \
1403 + Python/mysnprintf.o \
1404 + Python/pyarena.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 \
1413 + Python/pystrtod.o \
1414 + Python/$(DYNLOADFILE) \
1419 +##########################################################################
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 \
1458 +##########################################################################
1459 +# objects that get linked into the Python library
1461 + Modules/_typesmodule.o \
1462 + Modules/getbuildinfo.o \
1470 +#########################################################################
1474 +all: $(BUILDPYTHON) oldsharedmods sharedmods
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)
1482 +platform: $(BUILDPYTHON)
1483 + $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
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;; \
1493 +# Build static library
1494 +# avoid long command lines, same as LIBRARY_OBJS
1495 +$(LIBRARY): $(LIBRARY_OBJS)
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)
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) $@; \
1511 + $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
1514 +libpython$(VERSION).sl: $(LIBRARY_OBJS)
1515 + $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM)
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
1520 +RESSRCDIR=$(srcdir)/Mac/Resources/framework
1521 +$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
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); \
1535 + /usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
1536 + @LIBTOOL_CRUFT@ ;\
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
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); \
1561 +oldsharedmods: $(SHAREDMODS)
1564 +Makefile Modules/config.c: Makefile.pre \
1565 + $(srcdir)/Modules/config.c.in \
1567 + Modules/Setup.config \
1569 + Modules/Setup.local
1570 + $(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
1572 + Modules/Setup.config \
1573 + Modules/Setup.local \
1575 + @mv config.c Modules
1576 + @echo "The Makefile was updated, you may need to re-run make."
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 "-----------------------------------------------"; \
1589 +############################################################################
1590 +# Special rules for object files
1592 +Modules/getbuildinfo.o: $(PARSER_OBJS) \
1598 + $(srcdir)/Modules/getbuildinfo.c
1599 + $(CC) -c $(PY_CFLAGS) -DSVNVERSION=\"`LC_ALL=C $(SVNVERSION)`\" -o $@ $(srcdir)/Modules/getbuildinfo.c
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
1609 +Modules/python.o: $(srcdir)/Modules/python.c
1610 + $(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
1613 +$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
1615 + -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
1617 +$(PGEN): $(PGENOBJS)
1618 + $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
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
1625 +Parser/tokenizer_pgen.o: $(srcdir)/Parser/tokenizer.c
1627 +$(AST_H): $(AST_ASDL) $(ASDLGEN_FILES)
1628 + $(ASDLGEN) -h $(AST_H_DIR) $(AST_ASDL)
1630 +$(AST_C): $(AST_ASDL) $(ASDLGEN_FILES)
1631 + $(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL)
1633 +Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H)
1635 +Python/getplatform.o: $(srcdir)/Python/getplatform.c
1636 + $(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
1638 +Python/importdl.o: $(srcdir)/Python/importdl.c
1639 + $(CC) -c $(PY_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c
1641 +Objects/unicodectype.o: $(srcdir)/Objects/unicodectype.c \
1642 + $(srcdir)/Objects/unicodetype_db.h
1644 +############################################################################
1648 + Include/Python.h \
1649 + Include/Python-ast.h \
1651 + Include/abstract.h \
1652 + Include/boolobject.h \
1653 + Include/bufferobject.h \
1655 + Include/classobject.h \
1656 + Include/cobject.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 \
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 \
1702 +$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
1705 +######################################################################
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
1715 +TESTOPTS= -l $(EXTRATESTOPTS)
1716 +TESTPROG= $(srcdir)/Lib/test/regrtest.py
1717 +TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -E -tt
1719 + -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
1720 + -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
1721 + $(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
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
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" ;\
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
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)'"; \
1747 + $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw
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)
1757 +MEMTESTOPTS= $(QUICKTESTOPTS) -x test_dl test___all__ test_fork1 \
1759 +memtest: all platform
1760 + -rm -f $(srcdir)/Lib/test/*.py[co]
1761 + -$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
1762 + $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
1764 +# Install everything
1765 +install: @FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@
1767 +# Install almost everything without disturbing previous versions
1768 +altinstall: @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \
1769 + sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@
1771 +# Install shared libraries enabled by Setup
1772 +DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED)
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`; \
1783 + @for i in $(DESTDIRS); \
1785 + if test ! -d $(DESTDIR)$$i; then \
1786 + echo "Creating directory $$i"; \
1787 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
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); \
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)
1803 +# Install the interpreter with $(VERSION) affixed
1804 +# This goes into $(exec_prefix)
1805 +altbininstall: $(BUILDPYTHON)
1806 + @for i in $(BINDIR) $(LIBDIR); \
1808 + if test ! -d $(DESTDIR)$$i; then \
1809 + echo "Creating directory $$i"; \
1810 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
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); \
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)); \
1827 +# Install the manual page
1829 + @for i in $(MANDIR) $(MANDIR)/man1; \
1831 + if test ! -d $(DESTDIR)$$i; then \
1832 + echo "Creating directory $$i"; \
1833 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1837 + $(INSTALL_DATA) $(srcdir)/Misc/python.man \
1838 + $(DESTDIR)$(MANDIR)/man1/python.1
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); \
1869 + if test ! -d $(DESTDIR)$$i; then \
1870 + echo "Creating directory $$i"; \
1871 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1875 + @for d in $(LIBSUBDIRS); \
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; \
1886 + @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.doc $(srcdir)/Lib/*.egg-info ; \
1888 + if test -x $$i; then \
1889 + $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \
1890 + echo $(INSTALL_SCRIPT) $$i $(LIBDEST); \
1892 + $(INSTALL_DATA) $$i $(DESTDIR)$(LIBDEST); \
1893 + echo $(INSTALL_DATA) $$i $(LIBDEST); \
1896 + @for d in $(LIBSUBDIRS); \
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; \
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; \
1915 + echo $(INSTALL_DATA) $$i $$b; \
1916 + $(INSTALL_DATA) $$i $(DESTDIR)$$b; \
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
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
1949 +# Install the include files
1950 +INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY)
1952 + @for i in $(INCLDIRSTOMAKE); \
1954 + if test ! -d $(DESTDIR)$$i; then \
1955 + echo "Creating directory $$i"; \
1956 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
1960 + @for i in $(srcdir)/Include/*.h; \
1962 + echo $(INSTALL_DATA) $$i $(INCLUDEPY); \
1963 + $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \
1965 + $(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h
1967 +# Install the library and miscellaneous stuff needed for extending/embedding
1968 +# This goes into $(exec_prefix)
1969 +LIBPL= $(LIBP)/config
1971 + @for i in $(LIBDIR) $(LIBP) $(LIBPL); \
1973 + if test ! -d $(DESTDIR)$$i; then \
1974 + echo "Creating directory $$i"; \
1975 + $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$$i; \
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) ; \
1984 + $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
1985 + $(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
1988 + echo Skip install of $(LIBRARY) - use make frameworkinstall; \
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
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."; \
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."; \
2032 +# Install the dynamically loadable modules
2033 +# This goes into $(exec_prefix)
2035 + $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
2036 + --prefix=$(prefix) \
2037 + --install-scripts=$(BINDIR) \
2038 + --install-platlib=$(DESTSHARED) \
2039 + --root=/$(DESTDIR)
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
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
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.
2057 +frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib
2059 +frameworkinstallstructure: $(LDLIBRARY)
2060 + @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
2061 + echo Not configured with --enable-framework; \
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; \
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)
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)"
2090 +# This installs the IDE, the Launcher and other apps into /Applications
2091 +frameworkinstallapps:
2092 + cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)"
2094 +# This install the unix python and pythonw tools in /usr/local/bin
2095 +frameworkinstallunixtools:
2096 + cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)"
2098 +frameworkaltinstallunixtools:
2099 + cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)"
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)"
2106 +# This installs a few of the useful scripts in Tools/scripts
2108 + SRCDIR=$(srcdir) $(RUNSHARED) \
2109 + ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \
2110 + --prefix=$(prefix) \
2111 + --install-scripts=$(BINDIR) \
2112 + --root=/$(DESTDIR)
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
2119 +# Run the configure script.
2120 +config.status: $(srcdir)/configure
2121 + $(SHELL) $(srcdir)/configure $(CONFIG_ARGS)
2123 +.PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre
2125 +# Some make's put the object file in the current directory
2127 + $(CC) -c $(PY_CFLAGS) -o $@ $<
2129 +# Run reindent on the library
2131 + ./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
2133 +# Rerun configure with the same options as it was run last time,
2134 +# provided the config.status script exists
2136 + $(SHELL) config.status --recheck
2137 + $(SHELL) config.status
2139 +# Rebuild the configure script from configure.in; also rebuild pyconfig.h.in
2141 + (cd $(srcdir); autoconf)
2142 + (cd $(srcdir); autoheader)
2144 +# Create a tags file for vi
2147 + ctags -w -t Include/*.h; \
2148 + for i in $(SRCDIRS); do ctags -w -t -a $$i/*.[ch]; \
2152 +# Create a tags file for GNU Emacs
2155 + etags Include/*.h; \
2156 + for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done
2158 +# Sanitation targets -- clean leaves libraries, executables and tags
2159 +# files, which clobber removes those as well
2161 + find $(srcdir) -name '*.py[co]' -exec rm -f {} ';'
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
2170 + -rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
2172 + config.cache config.log pyconfig.h Modules/config.c
2173 + -rm -rf build platform
2174 + -rm -rf $(PYTHONFRAMEWORKDIR)
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
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 {} ';'
2188 +# Check for smelly exported symbols (not starting with Py/_Py)
2190 + nm -p $(LIBRARY) | \
2191 + sed -n "/ [TDB] /s/.* //p" | grep -v "^_*Py" | sort -u; \
2193 +# Find files with funny names
2195 + find $(DISTDIRS) -type d \
2196 + -o -name '*.[chs]' \
2198 + -o -name '*.doc' \
2199 + -o -name '*.sty' \
2200 + -o -name '*.bib' \
2201 + -o -name '*.dat' \
2205 + -o -name '*.tex' \
2206 + -o -name '*,[vpt]' \
2207 + -o -name 'Setup' \
2208 + -o -name 'Setup.*' \
2210 + -o -name Makefile \
2211 + -o -name ChangeLog \
2212 + -o -name Repository \
2214 + -o -name Entries \
2218 + -o -name .cvsignore \
2219 + -o -name MANIFEST \
2224 +Python/thread.o: @THREADHEADERS@
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
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
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 */
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__ */
2265 #if defined(PYCC_VACPP)
2266 extern int mkdir(char *);
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 *);
2272 extern int mkdir(const char *, mode_t);
2273 @@ -189,9 +200,13 @@
2275 extern int chmod(const char *, int);
2277 +#ifndef __MINGW32__
2278 extern int chmod(const char *, mode_t);
2281 +#ifndef __MINGW32__
2282 extern int chown(const char *, uid_t, gid_t);
2284 extern char *getcwd(char *, int);
2285 extern char *strerror(int);
2286 extern int link(const char *, const char *);
2292 +#if defined(_MSC_VER) || defined(__MINGW32__)
2293 #ifdef HAVE_DIRECT_H
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 */
2305 @@ -2328,7 +2343,7 @@
2306 Py_FileSystemDefaultEncoding, &path, &mode))
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__)
2313 res = mkdir(path, mode);
2314 @@ -7972,7 +7987,7 @@
2319 +#if defined(MS_WINDOWS) && !defined(__MINGW32__)
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__},
2328 +#if defined(MS_WINDOWS) && !defined(__MINGW32__)
2329 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
2333 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
2335 @@ -8653,7 +8668,7 @@
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"
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
2349 +/* POSIX module implementation */
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. */
2361 +/* See also ../Dos/dosmodule.c */
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.
2369 +# pragma weak lchown
2370 +# pragma weak statvfs
2371 +# pragma weak fstatvfs
2373 +#endif /* __APPLE__ */
2375 +#define PY_SSIZE_T_CLEAN
2377 +#include "Python.h"
2378 +#include "structseq.h"
2381 +# include <unixio.h>
2382 +#endif /* defined(__VMS) */
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.");
2394 +#ifndef Py_USING_UNICODE
2395 +/* This is used in signatures of functions. */
2396 +#define Py_UNICODE void
2399 +#if defined(PYOS_OS2)
2401 +#define INCL_DOSERRORS
2402 +#define INCL_DOSPROCESS
2403 +#define INCL_NOPMAPI
2405 +#if defined(PYCC_GCC)
2409 +#include <process.h>
2411 +#include "osdefs.h"
2414 +#ifdef HAVE_SYS_TYPES_H
2415 +#include <sys/types.h>
2416 +#endif /* HAVE_SYS_TYPES_H */
2418 +#ifdef HAVE_SYS_STAT_H
2419 +#include <sys/stat.h>
2420 +#endif /* HAVE_SYS_STAT_H */
2422 +#ifdef HAVE_SYS_WAIT_H
2423 +#include <sys/wait.h> /* For WNOHANG */
2426 +#ifdef HAVE_SIGNAL_H
2427 +#include <signal.h>
2430 +#ifdef HAVE_FCNTL_H
2432 +#endif /* HAVE_FCNTL_H */
2438 +#ifdef HAVE_SYSEXITS_H
2439 +#include <sysexits.h>
2440 +#endif /* HAVE_SYSEXITS_H */
2442 +#ifdef HAVE_SYS_LOADAVG_H
2443 +#include <sys/loadavg.h>
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>
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
2459 +#include <process.h>
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
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
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
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
2500 +#define HAVE_POPEN 1
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__ */
2513 +#if defined(__sgi)&&_COMPILER_VERSION>=700
2514 +/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
2516 +extern char *ctermid_r(char *);
2519 +#ifndef HAVE_UNISTD_H
2520 +#if defined(PYCC_VACPP)
2521 +extern int mkdir(char *);
2523 +#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
2524 +extern int mkdir(const char *);
2526 +extern int mkdir(const char *, mode_t);
2529 +#if defined(__IBMC__) || defined(__IBMCPP__)
2530 +extern int chdir(char *);
2531 +extern int rmdir(char *);
2533 +extern int chdir(const char *);
2534 +extern int rmdir(const char *);
2536 +#ifdef __BORLANDC__
2537 +extern int chmod(const char *, int);
2539 +extern int chmod(const char *, mode_t);
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 */
2553 +extern int lstat(const char *, struct stat *);
2554 +#endif /* HAVE_LSTAT */
2555 +#endif /* !HAVE_UNISTD_H */
2557 +#endif /* !_MSC_VER */
2559 +#ifdef HAVE_UTIME_H
2561 +#endif /* HAVE_UTIME_H */
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 */
2568 +#ifdef HAVE_SYS_TIMES_H
2569 +#include <sys/times.h>
2570 +#endif /* HAVE_SYS_TIMES_H */
2572 +#ifdef HAVE_SYS_PARAM_H
2573 +#include <sys/param.h>
2574 +#endif /* HAVE_SYS_PARAM_H */
2576 +#ifdef HAVE_SYS_UTSNAME_H
2577 +#include <sys/utsname.h>
2578 +#endif /* HAVE_SYS_UTSNAME_H */
2580 +#ifdef HAVE_DIRENT_H
2581 +#include <dirent.h>
2582 +#define NAMLEN(dirent) strlen((dirent)->d_name)
2584 +#if defined(__WATCOMC__) && !defined(__QNX__)
2585 +#include <direct.h>
2586 +#define NAMLEN(dirent) strlen((dirent)->d_name)
2588 +#define dirent direct
2589 +#define NAMLEN(dirent) (dirent)->d_namlen
2591 +#ifdef HAVE_SYS_NDIR_H
2592 +#include <sys/ndir.h>
2594 +#ifdef HAVE_SYS_DIR_H
2595 +#include <sys/dir.h>
2603 +#ifdef HAVE_DIRECT_H
2604 +#include <direct.h>
2609 +#ifdef HAVE_PROCESS_H
2610 +#include <process.h>
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 */
2620 +#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2625 +#if defined(PATH_MAX) && PATH_MAX > 1024
2626 +#define MAXPATHLEN PATH_MAX
2628 +#define MAXPATHLEN 1024
2630 +#endif /* MAXPATHLEN */
2633 +/* Emulate some macros on systems that have a union instead of macros */
2636 +#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
2639 +#ifndef WEXITSTATUS
2640 +#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
2644 +#define WTERMSIG(u_wait) ((u_wait).w_termsig)
2647 +#define WAIT_TYPE union wait
2648 +#define WAIT_STATUS_INT(s) (s.w_status)
2650 +#else /* !UNION_WAIT */
2651 +#define WAIT_TYPE int
2652 +#define WAIT_STATUS_INT(s) (s)
2653 +#endif /* UNION_WAIT */
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
2661 +#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
2662 +#define USE_TMPNAM_R
2665 +/* choose the appropriate stat and fstat functions and return structs */
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
2673 +# define FSTAT fstat
2674 +# define STRUCT_STAT struct stat
2677 +#if defined(MAJOR_IN_MKDEV)
2678 +#include <sys/mkdev.h>
2680 +#if defined(MAJOR_IN_SYSMACROS)
2681 +#include <sys/sysmacros.h>
2683 +#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
2684 +#include <sys/mkdev.h>
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().
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 */
2700 +convertenviron(void)
2707 +#ifdef WITH_NEXT_FRAMEWORK
2708 + if (environ == NULL)
2709 + environ = *_NSGetEnviron();
2711 + if (environ == NULL)
2713 + /* This part ignores errors */
2714 + for (e = environ; *e != NULL; e++) {
2717 + char *p = strchr(*e, '=');
2720 + k = PyString_FromStringAndSize(*e, (int)(p-*e));
2725 + v = PyString_FromString(p+1);
2731 + if (PyDict_GetItem(d, k) == NULL) {
2732 + if (PyDict_SetItem(d, k, v) != 0)
2738 +#if defined(PYOS_OS2)
2741 + char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
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);
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);
2761 +/* Set a POSIX-specific error from errno, and return NULL */
2766 + return PyErr_SetFromErrno(PyExc_OSError);
2769 +posix_error_with_filename(char* name)
2771 + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
2774 +#ifdef Py_WIN_WIDE_FILENAMES
2776 +posix_error_with_unicode_filename(Py_UNICODE* name)
2778 + return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
2780 +#endif /* Py_WIN_WIDE_FILENAMES */
2784 +posix_error_with_allocated_filename(char* name)
2786 + PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
2793 +win32_error(char* function, char* filename)
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.
2800 + errno = GetLastError();
2802 + return PyErr_SetFromWindowsErrWithFilename(errno, filename);
2804 + return PyErr_SetFromWindowsErr(errno);
2807 +#ifdef Py_WIN_WIDE_FILENAMES
2809 +win32_error_unicode(char* function, Py_UNICODE* filename)
2811 + /* XXX - see win32_error for comments on 'function' */
2812 + errno = GetLastError();
2814 + return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
2816 + return PyErr_SetFromWindowsErr(errno);
2819 +static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
2823 +/* Function suitable for O& conversion */
2825 +convert_to_unicode(PyObject *arg, void* _param)
2827 + PyObject **param = (PyObject**)_param;
2828 + if (PyUnicode_CheckExact(arg)) {
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;
2840 + *param = PyUnicode_FromEncodedObject(arg,
2841 + Py_FileSystemDefaultEncoding,
2843 + return (*param) != NULL;
2846 +#endif /* Py_WIN_WIDE_FILENAMES */
2850 +#if defined(PYOS_OS2)
2851 +/**********************************************************************
2852 + * Helper Function to Trim and Format OS/2 Messages
2853 + **********************************************************************/
2855 +os2_formatmsg(char *msgbuf, int msglen, char *reason)
2857 + msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
2859 + if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
2860 + char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
2862 + while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
2863 + *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
2866 + /* Add Optional Reason Text */
2868 + strcat(msgbuf, " : ");
2869 + strcat(msgbuf, reason);
2873 +/**********************************************************************
2874 + * Decode an OS/2 Operating System Error Code
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.
2880 + * The messages for errors returned from the OS/2 kernel reside in
2881 + * the file OSO001.MSG in the \OS2 directory hierarchy.
2883 + **********************************************************************/
2885 +os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
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
2896 + if (rc == NO_ERROR)
2897 + os2_formatmsg(msgbuf, msglen, reason);
2899 + PyOS_snprintf(msgbuf, msgbuflen,
2900 + "unknown OS error #%d", errorcode);
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. */
2909 +static PyObject * os2_error(int code)
2914 + os2_strerror(text, sizeof(text), code, "");
2916 + v = Py_BuildValue("(is)", code, text);
2918 + PyErr_SetObject(PyExc_OSError, v);
2921 + return NULL; /* Signal to Python that an Exception is Pending */
2926 +/* POSIX generic methods */
2929 +posix_fildes(PyObject *fdobj, int (*func)(int))
2933 + fd = PyObject_AsFileDescriptor(fdobj);
2936 + Py_BEGIN_ALLOW_THREADS
2937 + res = (*func)(fd);
2938 + Py_END_ALLOW_THREADS
2940 + return posix_error();
2941 + Py_INCREF(Py_None);
2945 +#ifdef Py_WIN_WIDE_FILENAMES
2947 +unicode_file_names(void)
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;
2955 + return canusewide;
2960 +posix_1str(PyObject *args, char *format, int (*func)(const char*))
2962 + char *path1 = NULL;
2964 + if (!PyArg_ParseTuple(args, format,
2965 + Py_FileSystemDefaultEncoding, &path1))
2967 + Py_BEGIN_ALLOW_THREADS
2968 + res = (*func)(path1);
2969 + Py_END_ALLOW_THREADS
2971 + return posix_error_with_allocated_filename(path1);
2972 + PyMem_Free(path1);
2973 + Py_INCREF(Py_None);
2978 +posix_2str(PyObject *args,
2980 + int (*func)(const char *, const char *))
2982 + char *path1 = NULL, *path2 = NULL;
2984 + if (!PyArg_ParseTuple(args, format,
2985 + Py_FileSystemDefaultEncoding, &path1,
2986 + Py_FileSystemDefaultEncoding, &path2))
2988 + Py_BEGIN_ALLOW_THREADS
2989 + res = (*func)(path1, path2);
2990 + Py_END_ALLOW_THREADS
2991 + PyMem_Free(path1);
2992 + PyMem_Free(path2);
2994 + /* XXX how to report both path1 and path2??? */
2995 + return posix_error();
2996 + Py_INCREF(Py_None);
3000 +#ifdef Py_WIN_WIDE_FILENAMES
3002 +win32_1str(PyObject* args, char* func,
3003 + char* format, BOOL (__stdcall *funcA)(LPCSTR),
3004 + char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
3009 + if (unicode_file_names()) {
3010 + if (!PyArg_ParseTuple(args, wformat, &uni))
3013 + Py_BEGIN_ALLOW_THREADS
3014 + result = funcW(PyUnicode_AsUnicode(uni));
3015 + Py_END_ALLOW_THREADS
3017 + return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
3018 + Py_INCREF(Py_None);
3022 + if (!PyArg_ParseTuple(args, format, &ansi))
3024 + Py_BEGIN_ALLOW_THREADS
3025 + result = funcA(ansi);
3026 + Py_END_ALLOW_THREADS
3028 + return win32_error(func, ansi);
3029 + Py_INCREF(Py_None);
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>: */
3040 +win32_chdir(LPCSTR path)
3042 + char new_path[MAX_PATH+1];
3044 + char env[4] = "=x:";
3046 + if(!SetCurrentDirectoryA(path))
3048 + result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
3051 + /* In the ANSI API, there should not be any paths longer
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. */
3058 + env[1] = new_path[0];
3059 + return SetEnvironmentVariableA(env, new_path);
3062 +/* The Unicode version differs from the ANSI version
3063 + since the current directory might exceed MAX_PATH characters */
3065 +win32_wchdir(LPCWSTR path)
3067 + wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
3069 + wchar_t env[4] = L"=x:";
3071 + if(!SetCurrentDirectoryW(path))
3073 + result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
3076 + if (result > MAX_PATH+1) {
3077 + new_path = malloc(result);
3079 + SetLastError(ERROR_OUTOFMEMORY);
3083 + if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
3084 + wcsncmp(new_path, L"//", 2) == 0)
3085 + /* UNC path, nothing to do. */
3087 + env[1] = new_path[0];
3088 + result = SetEnvironmentVariableW(env, new_path);
3089 + if (new_path != _new_path)
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.
3102 +#define HAVE_STAT_NSEC 1
3107 + unsigned short st_mode;
3114 + int st_atime_nsec;
3116 + int st_mtime_nsec;
3118 + int st_ctime_nsec;
3121 +static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
3124 +FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
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 */
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);
3137 +time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
3139 + /* XXX endianness */
3141 + out = time_in + secs_between_epochs;
3142 + out = out * 10000000 + nsec_in / 100;
3143 + memcpy(out_ptr, &out, sizeof(out));
3146 +/* Below, we *know* that ugo+r is 0444 */
3147 +#if _S_IREAD != 0400
3148 +#error Unsupported C library
3151 +attributes_to_mode(DWORD attr)
3154 + if (attr & FILE_ATTRIBUTE_DIRECTORY)
3155 + m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
3158 + if (attr & FILE_ATTRIBUTE_READONLY)
3166 +attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
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);
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);
3185 + HINSTANCE hKernel32;
3189 + hKernel32 = GetModuleHandle("KERNEL32");
3190 + *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
3191 + *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
3195 +attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
3198 + WIN32_FIND_DATAA FileData;
3199 + hFindFile = FindFirstFileA(pszFile, &FileData);
3200 + if (hFindFile == INVALID_HANDLE_VALUE)
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;
3213 +attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
3216 + WIN32_FIND_DATAW FileData;
3217 + hFindFile = FindFirstFileW(pszFile, &FileData);
3218 + if (hFindFile == INVALID_HANDLE_VALUE)
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;
3231 +Py_GetFileAttributesExA(LPCSTR pszFile,
3232 + GET_FILEEX_INFO_LEVELS level,
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. */
3242 + result = gfaxa(pszFile, level, pv);
3243 + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
3246 + /* It's either not present, or not implemented.
3247 + Emulate using FindFirstFile. */
3248 + if (level != GetFileExInfoStandard) {
3249 + SetLastError(ERROR_INVALID_PARAMETER);
3252 + /* Use GetFileAttributes to validate that the file name
3253 + does not contain wildcards (which FindFirstFile would
3255 + if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
3257 + return attributes_from_dir(pszFile, pfad);
3261 +Py_GetFileAttributesExW(LPCWSTR pszFile,
3262 + GET_FILEEX_INFO_LEVELS level,
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. */
3272 + result = gfaxw(pszFile, level, pv);
3273 + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
3276 + /* It's either not present, or not implemented.
3277 + Emulate using FindFirstFile. */
3278 + if (level != GetFileExInfoStandard) {
3279 + SetLastError(ERROR_INVALID_PARAMETER);
3282 + /* Use GetFileAttributes to validate that the file name
3283 + does not contain wildcards (which FindFirstFile would
3285 + if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
3287 + return attributes_from_dir_w(pszFile, pfad);
3291 +win32_stat(const char* path, struct win32_stat *result)
3293 + WIN32_FILE_ATTRIBUTE_DATA info;
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. */
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 */
3313 + code = attribute_data_to_stat(&info, result);
3316 + /* Set S_IFEXEC if it is an .exe, .bat, ... */
3317 + dot = strrchr(path, '.');
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;
3329 +win32_wstat(const wchar_t* path, struct win32_stat *result)
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. */
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 */
3351 + code = attribute_data_to_stat(&info, result);
3354 + /* Set IFEXEC if it is an .exe, .bat, ... */
3355 + dot = wcsrchr(path, '.');
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;
3367 +win32_fstat(int file_number, struct win32_stat *result)
3369 + BY_HANDLE_FILE_INFORMATION info;
3373 + h = (HANDLE)_get_osfhandle(file_number);
3375 + /* Protocol violation: we explicitly clear errno, instead of
3376 + setting it to a POSIX error. Callers should use GetLastError. */
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);
3385 + memset(result, 0, sizeof(*result));
3387 + type = GetFileType(h);
3388 + if (type == FILE_TYPE_UNKNOWN) {
3389 + DWORD error = GetLastError();
3393 + /* else: valid but unknown file */
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;
3404 + if (!GetFileInformationByHandle(h, &info)) {
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;
3420 +#endif /* MS_WINDOWS */
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\
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\
3431 +See os.stat for more information.");
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"},
3451 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3452 + {"st_blocks", "number of blocks allocated"},
3454 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3455 + {"st_rdev", "device type (if inode device)"},
3457 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3458 + {"st_flags", "user defined flags for file"},
3460 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3461 + {"st_gen", "generation number"},
3463 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3464 + {"st_birthtime", "time of creation"},
3469 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
3470 +#define ST_BLKSIZE_IDX 13
3472 +#define ST_BLKSIZE_IDX 12
3475 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3476 +#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
3478 +#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
3481 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3482 +#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
3484 +#define ST_RDEV_IDX ST_BLOCKS_IDX
3487 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3488 +#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
3490 +#define ST_FLAGS_IDX ST_RDEV_IDX
3493 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3494 +#define ST_GEN_IDX (ST_FLAGS_IDX+1)
3496 +#define ST_GEN_IDX ST_FLAGS_IDX
3499 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3500 +#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
3502 +#define ST_BIRTHTIME_IDX ST_GEN_IDX
3505 +static PyStructSequence_Desc stat_result_desc = {
3506 + "stat_result", /* name */
3507 + stat_result__doc__, /* doc */
3508 + stat_result_fields,
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\
3518 +See os.statvfs for more information.");
3520 +static PyStructSequence_Field statvfs_result_fields[] = {
3534 +static PyStructSequence_Desc statvfs_result_desc = {
3535 + "statvfs_result", /* name */
3536 + statvfs_result__doc__, /* doc */
3537 + statvfs_result_fields,
3541 +static int initialized;
3542 +static PyTypeObject StatResultType;
3543 +static PyTypeObject StatVFSResultType;
3544 +static newfunc structseq_new;
3547 +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3549 + PyStructSequence *result;
3552 + result = (PyStructSequence*)structseq_new(type, args, kwds);
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];
3565 + return (PyObject*)result;
3570 +/* If true, st_?time is float. */
3571 +static int _stat_float_times = 1;
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");
3581 +stat_float_times(PyObject* self, PyObject *args)
3584 + if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
3587 + /* Return old value */
3588 + return PyBool_FromLong(_stat_float_times);
3589 + _stat_float_times = newval;
3590 + Py_INCREF(Py_None);
3595 +fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
3597 + PyObject *fval,*ival;
3598 +#if SIZEOF_TIME_T > SIZEOF_LONG
3599 + ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
3601 + ival = PyInt_FromLong((long)sec);
3605 + if (_stat_float_times) {
3606 + fval = PyFloat_FromDouble(sec + 1e-9*nsec);
3611 + PyStructSequence_SET_ITEM(v, index, ival);
3612 + PyStructSequence_SET_ITEM(v, index+3, fval);
3615 +/* pack a system stat C structure into the Python stat tuple
3616 + (used by posix_stat() and posix_fstat()) */
3618 +_pystat_fromstructstat(STRUCT_STAT *st)
3620 + unsigned long ansec, mnsec, cnsec;
3621 + PyObject *v = PyStructSequence_New(&StatResultType);
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));
3630 + PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
3632 +#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
3633 + PyStructSequence_SET_ITEM(v, 2,
3634 + PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
3636 + PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
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));
3645 + PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
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;
3661 + ansec = mnsec = cnsec = 0;
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);
3667 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
3668 + PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
3669 + PyInt_FromLong((long)st->st_blksize));
3671 +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
3672 + PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
3673 + PyInt_FromLong((long)st->st_blocks));
3675 +#ifdef HAVE_STRUCT_STAT_ST_RDEV
3676 + PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
3677 + PyInt_FromLong((long)st->st_rdev));
3679 +#ifdef HAVE_STRUCT_STAT_ST_GEN
3680 + PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
3681 + PyInt_FromLong((long)st->st_gen));
3683 +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
3686 + unsigned long bsec,bnsec;
3687 + bsec = (long)st->st_birthtime;
3688 +#ifdef HAVE_STAT_TV_NSEC2
3689 + bnsec = st->st_birthtimespec.tv_nsec;
3693 + if (_stat_float_times) {
3694 + val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
3696 + val = PyInt_FromLong((long)bsec);
3698 + PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
3702 +#ifdef HAVE_STRUCT_STAT_ST_FLAGS
3703 + PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
3704 + PyInt_FromLong((long)st->st_flags));
3707 + if (PyErr_Occurred()) {
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.
3722 +#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
3723 +#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
3725 +#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
3729 +IsUNCRootA(char *path, int pathlen)
3731 + #define ISSLASH ISSLASHA
3735 + if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
3736 + /* minimum UNCRoot is \\x\y */
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 */
3744 + for (i = share; i < pathlen; i++)
3745 + if (ISSLASH(path[i])) break;
3746 + return (i != share && (i == pathlen || i == pathlen-1));
3751 +#ifdef Py_WIN_WIDE_FILENAMES
3753 +IsUNCRootW(Py_UNICODE *path, int pathlen)
3755 + #define ISSLASH ISSLASHW
3759 + if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
3760 + /* minimum UNCRoot is \\x\y */
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 */
3768 + for (i = share; i < pathlen; i++)
3769 + if (ISSLASH(path[i])) break;
3770 + return (i != share && (i == pathlen || i == pathlen-1));
3774 +#endif /* Py_WIN_WIDE_FILENAMES */
3775 +#endif /* MS_WINDOWS */
3778 +posix_do_stat(PyObject *self, PyObject *args,
3781 + int (*statfunc)(const char *, STRUCT_STAT *, ...),
3783 + int (*statfunc)(const char *, STRUCT_STAT *),
3786 + int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
3789 + char *path = NULL; /* pass this to stat; do not free() it */
3790 + char *pathfree = NULL; /* this memory must be free'd */
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);
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
3809 + return win32_error_unicode("stat", wpath);
3810 + return _pystat_fromstructstat(&st);
3812 + /* Drop the argument parsing error as narrow strings
3813 + are also valid. */
3818 + if (!PyArg_ParseTuple(args, format,
3819 + Py_FileSystemDefaultEncoding, &path))
3823 + Py_BEGIN_ALLOW_THREADS
3824 + res = (*statfunc)(path, &st);
3825 + Py_END_ALLOW_THREADS
3829 + result = win32_error("stat", pathfree);
3831 + result = posix_error_with_filename(pathfree);
3835 + result = _pystat_fromstructstat(&st);
3837 + PyMem_Free(pathfree);
3841 +/* POSIX methods */
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.");
3852 +posix_access(PyObject *self, PyObject *args)
3857 +#ifdef Py_WIN_WIDE_FILENAMES
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
3869 + /* Drop the argument parsing error as narrow strings
3870 + are also valid. */
3873 + if (!PyArg_ParseTuple(args, "eti:access",
3874 + Py_FileSystemDefaultEncoding, &path, &mode))
3876 + Py_BEGIN_ALLOW_THREADS
3877 + attr = GetFileAttributesA(path);
3878 + Py_END_ALLOW_THREADS
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));
3892 + if (!PyArg_ParseTuple(args, "eti:access",
3893 + Py_FileSystemDefaultEncoding, &path, &mode))
3895 + Py_BEGIN_ALLOW_THREADS
3896 + res = access(path, mode);
3897 + Py_END_ALLOW_THREADS
3899 + return PyBool_FromLong(res == 0);
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'.");
3922 +posix_ttyname(PyObject *self, PyObject *args)
3927 + if (!PyArg_ParseTuple(args, "i:ttyname", &id))
3931 + /* file descriptor 0 only, the default input device (stdin) */
3939 + ret = ttyname(id);
3942 + return posix_error();
3943 + return PyString_FromString(ret);
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.");
3953 +posix_ctermid(PyObject *self, PyObject *noargs)
3956 + char buffer[L_ctermid];
3958 +#ifdef USE_CTERMID_R
3959 + ret = ctermid_r(buffer);
3961 + ret = ctermid(buffer);
3964 + return posix_error();
3965 + return PyString_FromString(buffer);
3969 +PyDoc_STRVAR(posix_chdir__doc__,
3971 +Change the current working directory to the specified path.");
3974 +posix_chdir(PyObject *self, PyObject *args)
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);
3983 + return posix_1str(args, "et:chdir", chdir);
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.");
3994 +posix_fchdir(PyObject *self, PyObject *fdobj)
3996 + return posix_fildes(fdobj, fchdir);
3998 +#endif /* HAVE_FCHDIR */
4001 +PyDoc_STRVAR(posix_chmod__doc__,
4002 +"chmod(path, mode)\n\n\
4003 +Change the access permissions of a file.");
4006 +posix_chmod(PyObject *self, PyObject *args)
4008 + char *path = NULL;
4011 +#ifdef Py_WIN_WIDE_FILENAMES
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;
4022 + attr |= FILE_ATTRIBUTE_READONLY;
4023 + res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
4027 + Py_END_ALLOW_THREADS
4029 + return win32_error_unicode("chmod",
4030 + PyUnicode_AS_UNICODE(po));
4031 + Py_INCREF(Py_None);
4034 + /* Drop the argument parsing error as narrow strings
4035 + are also valid. */
4038 + if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
4041 + Py_BEGIN_ALLOW_THREADS
4042 + attr = GetFileAttributesA(path);
4043 + if (attr != 0xFFFFFFFF) {
4044 + if (i & _S_IWRITE)
4045 + attr &= ~FILE_ATTRIBUTE_READONLY;
4047 + attr |= FILE_ATTRIBUTE_READONLY;
4048 + res = SetFileAttributesA(path, attr);
4052 + Py_END_ALLOW_THREADS
4054 + win32_error("chmod", path);
4059 + Py_INCREF(Py_None);
4061 +#else /* Py_WIN_WIDE_FILENAMES */
4062 + if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
4065 + Py_BEGIN_ALLOW_THREADS
4066 + res = chmod(path, i);
4067 + Py_END_ALLOW_THREADS
4069 + return posix_error_with_allocated_filename(path);
4071 + Py_INCREF(Py_None);
4078 +PyDoc_STRVAR(posix_chroot__doc__,
4080 +Change root directory to path.");
4083 +posix_chroot(PyObject *self, PyObject *args)
4085 + return posix_1str(args, "et:chroot", chroot);
4090 +PyDoc_STRVAR(posix_fsync__doc__,
4091 +"fsync(fildes)\n\n\
4092 +force write of file with filedescriptor to disk.");
4095 +posix_fsync(PyObject *self, PyObject *fdobj)
4097 + return posix_fildes(fdobj, fsync);
4099 +#endif /* HAVE_FSYNC */
4101 +#ifdef HAVE_FDATASYNC
4104 +extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
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.");
4113 +posix_fdatasync(PyObject *self, PyObject *fdobj)
4115 + return posix_fildes(fdobj, fdatasync);
4117 +#endif /* HAVE_FDATASYNC */
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.");
4126 +posix_chown(PyObject *self, PyObject *args)
4128 + char *path = NULL;
4131 + if (!PyArg_ParseTuple(args, "etii:chown",
4132 + Py_FileSystemDefaultEncoding, &path,
4135 + Py_BEGIN_ALLOW_THREADS
4136 + res = chown(path, (uid_t) uid, (gid_t) gid);
4137 + Py_END_ALLOW_THREADS
4139 + return posix_error_with_allocated_filename(path);
4141 + Py_INCREF(Py_None);
4144 +#endif /* HAVE_CHOWN */
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.");
4153 +posix_lchown(PyObject *self, PyObject *args)
4155 + char *path = NULL;
4158 + if (!PyArg_ParseTuple(args, "etii:lchown",
4159 + Py_FileSystemDefaultEncoding, &path,
4162 + Py_BEGIN_ALLOW_THREADS
4163 + res = lchown(path, (uid_t) uid, (gid_t) gid);
4164 + Py_END_ALLOW_THREADS
4166 + return posix_error_with_allocated_filename(path);
4168 + Py_INCREF(Py_None);
4171 +#endif /* HAVE_LCHOWN */
4175 +PyDoc_STRVAR(posix_getcwd__doc__,
4176 +"getcwd() -> path\n\n\
4177 +Return a string representing the current working directory.");
4180 +posix_getcwd(PyObject *self, PyObject *noargs)
4185 + Py_BEGIN_ALLOW_THREADS
4186 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
4187 + res = _getcwd2(buf, sizeof buf);
4189 + res = getcwd(buf, sizeof buf);
4191 + Py_END_ALLOW_THREADS
4193 + return posix_error();
4194 + return PyString_FromString(buf);
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.");
4203 +posix_getcwdu(PyObject *self, PyObject *noargs)
4208 +#ifdef Py_WIN_WIDE_FILENAMES
4210 + if (unicode_file_names()) {
4211 + wchar_t wbuf[1026];
4212 + wchar_t *wbuf2 = wbuf;
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));
4222 + len = GetCurrentDirectoryW(len, wbuf2);
4224 + Py_END_ALLOW_THREADS
4230 + if (wbuf2 != wbuf) free(wbuf2);
4231 + return win32_error("getcwdu", NULL);
4233 + resobj = PyUnicode_FromWideChar(wbuf2, len);
4234 + if (wbuf2 != wbuf) free(wbuf2);
4239 + Py_BEGIN_ALLOW_THREADS
4240 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
4241 + res = _getcwd2(buf, sizeof buf);
4243 + res = getcwd(buf, sizeof buf);
4245 + Py_END_ALLOW_THREADS
4247 + return posix_error();
4248 + return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
4255 +PyDoc_STRVAR(posix_link__doc__,
4256 +"link(src, dst)\n\n\
4257 +Create a hard link to a file.");
4260 +posix_link(PyObject *self, PyObject *args)
4262 + return posix_2str(args, "etet:link", link);
4264 +#endif /* HAVE_LINK */
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\
4271 + path: path of directory to list\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.");
4277 +posix_listdir(PyObject *self, PyObject *args)
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)
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 */
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()) {
4296 + if (PyArg_ParseTuple(args, "U:listdir", &po)) {
4297 + WIN32_FIND_DATAW wFileData;
4298 + Py_UNICODE *wnamebuf;
4300 + /* Overallocate for \\*.*\0 */
4301 + len = PyUnicode_GET_SIZE(po);
4302 + wnamebuf = malloc((len + 5) * sizeof(wchar_t));
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) {
4316 + hFindFile = FindFirstFileW(wnamebuf, &wFileData);
4317 + if (hFindFile == INVALID_HANDLE_VALUE) {
4318 + int error = GetLastError();
4319 + if (error == ERROR_FILE_NOT_FOUND) {
4324 + win32_error_unicode("FindFirstFileW", wnamebuf);
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));
4338 + if (PyList_Append(d, v) != 0) {
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) {
4353 + win32_error_unicode("FindNextFileW", wnamebuf);
4354 + FindClose(hFindFile);
4358 + } while (result == TRUE);
4360 + if (FindClose(hFindFile) == FALSE) {
4362 + win32_error_unicode("FindClose", wnamebuf);
4369 + /* Drop the argument parsing error as narrow strings
4370 + are also valid. */
4375 + if (!PyArg_ParseTuple(args, "et#:listdir",
4376 + Py_FileSystemDefaultEncoding, &bufptr, &len))
4379 + char ch = namebuf[len-1];
4380 + if (ch != SEP && ch != ALTSEP && ch != ':')
4381 + namebuf[len++] = '/';
4383 + strcpy(namebuf + len, "*.*");
4385 + if ((d = PyList_New(0)) == NULL)
4388 + hFindFile = FindFirstFile(namebuf, &FileData);
4389 + if (hFindFile == INVALID_HANDLE_VALUE) {
4390 + int error = GetLastError();
4391 + if (error == ERROR_FILE_NOT_FOUND)
4394 + return win32_error("FindFirstFile", namebuf);
4397 + /* Skip over . and .. */
4398 + if (strcmp(FileData.cFileName, ".") != 0 &&
4399 + strcmp(FileData.cFileName, "..") != 0) {
4400 + v = PyString_FromString(FileData.cFileName);
4406 + if (PyList_Append(d, v) != 0) {
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) {
4421 + win32_error("FindNextFile", namebuf);
4422 + FindClose(hFindFile);
4425 + } while (result == TRUE);
4427 + if (FindClose(hFindFile) == FALSE) {
4429 + return win32_error("FindClose", namebuf);
4434 +#elif defined(PYOS_OS2)
4437 +#define MAX_PATH CCHMAXPATH
4442 + char namebuf[MAX_PATH+5];
4444 + ULONG srchcnt = 1;
4448 + if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
4450 + if (len >= MAX_PATH) {
4451 + PyErr_SetString(PyExc_ValueError, "path too long");
4454 + strcpy(namebuf, name);
4455 + for (pt = namebuf; *pt; pt++)
4456 + if (*pt == ALTSEP)
4458 + if (namebuf[len-1] != SEP)
4459 + namebuf[len++] = SEP;
4460 + strcpy(namebuf + len, "*.*");
4462 + if ((d = PyList_New(0)) == NULL)
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) */
4472 + if (rc != NO_ERROR) {
4474 + return posix_error_with_filename(name);
4477 + if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
4479 + if (ep.achName[0] == '.'
4480 + && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
4481 + continue; /* Skip Over "." and ".." Names */
4483 + strcpy(namebuf, ep.achName);
4485 + /* Leave Case of Name Alone -- In Native Form */
4486 + /* (Removed Forced Lowercasing Code) */
4488 + v = PyString_FromString(namebuf);
4494 + if (PyList_Append(d, v) != 0) {
4501 + } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
4507 + char *name = NULL;
4510 + struct dirent *ep;
4511 + int arg_is_unicode = 1;
4513 + if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
4514 + arg_is_unicode = 0;
4517 + if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
4519 + if ((dirp = opendir(name)) == NULL) {
4520 + return posix_error_with_allocated_filename(name);
4522 + if ((d = PyList_New(0)) == NULL) {
4529 + Py_BEGIN_ALLOW_THREADS
4530 + ep = readdir(dirp);
4531 + Py_END_ALLOW_THREADS
4534 + if (ep->d_name[0] == '.' &&
4535 + (NAMLEN(ep) == 1 ||
4536 + (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4538 + v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
4544 +#ifdef Py_USING_UNICODE
4545 + if (arg_is_unicode) {
4548 + w = PyUnicode_FromEncodedObject(v,
4549 + Py_FileSystemDefaultEncoding,
4556 + /* fall back to the original byte string, as
4557 + discussed in patch #683592 */
4562 + if (PyList_Append(d, v) != 0) {
4570 + if (errno != 0 && d != NULL) {
4571 + /* readdir() returned NULL and set errno */
4574 + return posix_error_with_allocated_filename(name);
4581 +#endif /* which OS */
4582 +} /* end of posix_listdir */
4585 +/* A helper function for abspath on win32 */
4587 +posix__getfullpathname(PyObject *self, PyObject *args)
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];
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]),
4604 + return win32_error("GetFullPathName", "");
4605 + return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
4607 + /* Drop the argument parsing error as narrow strings
4608 + are also valid. */
4612 + if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
4613 + Py_FileSystemDefaultEncoding, &inbufp,
4616 + if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
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);
4623 + return PyString_FromString(outbuf);
4624 +} /* end of posix__getfullpathname */
4625 +#endif /* MS_WINDOWS */
4627 +PyDoc_STRVAR(posix_mkdir__doc__,
4628 +"mkdir(path [, mode=0777])\n\n\
4629 +Create a directory.");
4632 +posix_mkdir(PyObject *self, PyObject *args)
4635 + char *path = NULL;
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
4648 + return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
4649 + Py_INCREF(Py_None);
4652 + /* Drop the argument parsing error as narrow strings
4653 + are also valid. */
4656 + if (!PyArg_ParseTuple(args, "et|i:mkdir",
4657 + Py_FileSystemDefaultEncoding, &path, &mode))
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
4665 + win32_error("mkdir", path);
4670 + Py_INCREF(Py_None);
4674 + if (!PyArg_ParseTuple(args, "et|i:mkdir",
4675 + Py_FileSystemDefaultEncoding, &path, &mode))
4677 + Py_BEGIN_ALLOW_THREADS
4678 +#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
4679 + res = mkdir(path);
4681 + res = mkdir(path, mode);
4683 + Py_END_ALLOW_THREADS
4685 + return posix_error_with_allocated_filename(path);
4687 + Py_INCREF(Py_None);
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>
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.");
4705 +posix_nice(PyObject *self, PyObject *args)
4707 + int increment, value;
4709 + if (!PyArg_ParseTuple(args, "i:nice", &increment))
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.
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! */
4723 + value = nice(increment);
4724 +#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
4726 + value = getpriority(PRIO_PROCESS, 0);
4728 + if (value == -1 && errno != 0)
4729 + /* either nice() or getpriority() returned an error */
4730 + return posix_error();
4731 + return PyInt_FromLong((long) value);
4733 +#endif /* HAVE_NICE */
4735 +PyDoc_STRVAR(posix_rename__doc__,
4736 +"rename(old, new)\n\n\
4737 +Rename a file or directory.");
4740 +posix_rename(PyObject *self, PyObject *args)
4743 + PyObject *o1, *o2;
4746 + if (unicode_file_names()) {
4747 + if (!PyArg_ParseTuple(args, "O&O&:rename",
4748 + convert_to_unicode, &o1,
4749 + convert_to_unicode, &o2))
4752 + Py_BEGIN_ALLOW_THREADS
4753 + result = MoveFileW(PyUnicode_AsUnicode(o1),
4754 + PyUnicode_AsUnicode(o2));
4755 + Py_END_ALLOW_THREADS
4759 + return win32_error("rename", NULL);
4760 + Py_INCREF(Py_None);
4764 + if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
4766 + Py_BEGIN_ALLOW_THREADS
4767 + result = MoveFileA(p1, p2);
4768 + Py_END_ALLOW_THREADS
4770 + return win32_error("rename", NULL);
4771 + Py_INCREF(Py_None);
4774 + return posix_2str(args, "etet:rename", rename);
4779 +PyDoc_STRVAR(posix_rmdir__doc__,
4781 +Remove a directory.");
4784 +posix_rmdir(PyObject *self, PyObject *args)
4787 + return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
4789 + return posix_1str(args, "et:rmdir", rmdir);
4794 +PyDoc_STRVAR(posix_stat__doc__,
4795 +"stat(path) -> stat result\n\n\
4796 +Perform a stat system call on the given path.");
4799 +posix_stat(PyObject *self, PyObject *args)
4802 + return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
4804 + return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
4810 +PyDoc_STRVAR(posix_system__doc__,
4811 +"system(command) -> exit_status\n\n\
4812 +Execute the command (a string) in a subshell.");
4815 +posix_system(PyObject *self, PyObject *args)
4819 + if (!PyArg_ParseTuple(args, "s:system", &command))
4821 + Py_BEGIN_ALLOW_THREADS
4822 + sts = system(command);
4823 + Py_END_ALLOW_THREADS
4824 + return PyInt_FromLong(sts);
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.");
4834 +posix_umask(PyObject *self, PyObject *args)
4837 + if (!PyArg_ParseTuple(args, "i:umask", &i))
4839 + i = (int)umask(i);
4841 + return posix_error();
4842 + return PyInt_FromLong((long)i);
4846 +PyDoc_STRVAR(posix_unlink__doc__,
4848 +Remove a file (same as remove(path)).");
4850 +PyDoc_STRVAR(posix_remove__doc__,
4852 +Remove a file (same as unlink(path)).");
4855 +posix_unlink(PyObject *self, PyObject *args)
4858 + return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
4860 + return posix_1str(args, "et:remove", unlink);
4866 +PyDoc_STRVAR(posix_uname__doc__,
4867 +"uname() -> (sysname, nodename, release, version, machine)\n\n\
4868 +Return a tuple identifying the current operating system.");
4871 +posix_uname(PyObject *self, PyObject *noargs)
4876 + Py_BEGIN_ALLOW_THREADS
4878 + Py_END_ALLOW_THREADS
4880 + return posix_error();
4881 + return Py_BuildValue("(sssss)",
4888 +#endif /* HAVE_UNAME */
4891 +extract_time(PyObject *t, long* sec, long* usec)
4894 + if (PyFloat_Check(t)) {
4895 + double tval = PyFloat_AsDouble(t);
4896 + PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
4899 + intval = PyInt_AsLong(intobj);
4900 + Py_DECREF(intobj);
4901 + if (intval == -1 && PyErr_Occurred())
4904 + *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
4906 + /* If rounding gave us a negative number,
4911 + intval = PyInt_AsLong(t);
4912 + if (intval == -1 && PyErr_Occurred())
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.");
4926 +posix_utime(PyObject *self, PyObject *args)
4928 +#ifdef Py_WIN_WIDE_FILENAMES
4930 + PyUnicodeObject *obwpath;
4931 + wchar_t *wpath = NULL;
4932 + char *apath = NULL;
4934 + long atimesec, mtimesec, ausec, musec;
4935 + FILETIME atime, mtime;
4936 + PyObject *result = NULL;
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);
4948 + /* Drop the argument parsing error as narrow strings
4949 + are also valid. */
4953 + if (!PyArg_ParseTuple(args, "etO:utime",
4954 + Py_FileSystemDefaultEncoding, &apath, &arg))
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);
4965 + PyMem_Free(apath);
4968 + if (arg == Py_None) {
4970 + GetSystemTime(&now);
4971 + if (!SystemTimeToFileTime(&now, &mtime) ||
4972 + !SystemTimeToFileTime(&now, &atime)) {
4973 + win32_error("utime", NULL);
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)");
4983 + if (extract_time(PyTuple_GET_ITEM(arg, 0),
4984 + &atimesec, &ausec) == -1)
4986 + time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
4987 + if (extract_time(PyTuple_GET_ITEM(arg, 1),
4988 + &mtimesec, &musec) == -1)
4990 + time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
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);
4999 + Py_INCREF(Py_None);
5002 + CloseHandle(hFile);
5004 +#else /* Py_WIN_WIDE_FILENAMES */
5006 + char *path = NULL;
5007 + long atime, mtime, ausec, musec;
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 */
5023 +#define ATIME buf[0]
5024 +#define MTIME buf[1]
5025 +#define UTIME_ARG buf
5026 +#endif /* HAVE_UTIMES */
5029 + if (!PyArg_ParseTuple(args, "etO:utime",
5030 + Py_FileSystemDefaultEncoding, &path, &arg))
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
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)");
5045 + if (extract_time(PyTuple_GET_ITEM(arg, 0),
5046 + &atime, &ausec) == -1) {
5050 + if (extract_time(PyTuple_GET_ITEM(arg, 1),
5051 + &mtime, &musec) == -1) {
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
5064 + Py_BEGIN_ALLOW_THREADS
5065 + res = utime(path, UTIME_ARG);
5066 + Py_END_ALLOW_THREADS
5067 +#endif /* HAVE_UTIMES */
5070 + return posix_error_with_allocated_filename(path);
5073 + Py_INCREF(Py_None);
5078 +#endif /* Py_WIN_WIDE_FILENAMES */
5082 +/* Process operations */
5084 +PyDoc_STRVAR(posix__exit__doc__,
5085 +"_exit(status)\n\n\
5086 +Exit to the system with specified status, without normal exit processing.");
5089 +posix__exit(PyObject *self, PyObject *args)
5092 + if (!PyArg_ParseTuple(args, "i:_exit", &sts))
5095 + return NULL; /* Make gcc -Wall happy */
5098 +#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
5100 +free_string_array(char **array, Py_ssize_t count)
5103 + for (i = 0; i < count; i++)
5104 + PyMem_Free(array[i]);
5111 +PyDoc_STRVAR(posix_execv__doc__,
5112 +"execv(path, args)\n\n\
5113 +Execute an executable path with arguments, replacing current process.\n\
5115 + path: path of executable file\n\
5116 + args: tuple or list of strings");
5119 +posix_execv(PyObject *self, PyObject *args)
5124 + Py_ssize_t i, argc;
5125 + PyObject *(*getitem)(PyObject *, Py_ssize_t);
5127 + /* execv has two arguments: (path, argv), where
5128 + argv is a list or tuple of strings. */
5130 + if (!PyArg_ParseTuple(args, "etO:execv",
5131 + Py_FileSystemDefaultEncoding,
5134 + if (PyList_Check(argv)) {
5135 + argc = PyList_Size(argv);
5136 + getitem = PyList_GetItem;
5138 + else if (PyTuple_Check(argv)) {
5139 + argc = PyTuple_Size(argv);
5140 + getitem = PyTuple_GetItem;
5143 + PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
5148 + argvlist = PyMem_NEW(char *, argc+1);
5149 + if (argvlist == NULL) {
5151 + return PyErr_NoMemory();
5153 + for (i = 0; i < argc; i++) {
5154 + if (!PyArg_Parse((*getitem)(argv, i), "et",
5155 + Py_FileSystemDefaultEncoding,
5157 + free_string_array(argvlist, i);
5158 + PyErr_SetString(PyExc_TypeError,
5159 + "execv() arg 2 must contain only strings");
5165 + argvlist[argc] = NULL;
5167 + execv(path, argvlist);
5169 + /* If we get here it's definitely an error */
5171 + free_string_array(argvlist, argc);
5173 + return posix_error();
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\
5181 + path: path of executable file\n\
5182 + args: tuple or list of arguments\n\
5183 + env: dictionary of strings mapping to strings");
5186 +posix_execve(PyObject *self, PyObject *args)
5189 + PyObject *argv, *env;
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;
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. */
5201 + if (!PyArg_ParseTuple(args, "etOO:execve",
5202 + Py_FileSystemDefaultEncoding,
5203 + &path, &argv, &env))
5205 + if (PyList_Check(argv)) {
5206 + argc = PyList_Size(argv);
5207 + getitem = PyList_GetItem;
5209 + else if (PyTuple_Check(argv)) {
5210 + argc = PyTuple_Size(argv);
5211 + getitem = PyTuple_GetItem;
5214 + PyErr_SetString(PyExc_TypeError,
5215 + "execve() arg 2 must be a tuple or list");
5218 + if (!PyMapping_Check(env)) {
5219 + PyErr_SetString(PyExc_TypeError,
5220 + "execve() arg 3 must be a mapping object");
5224 + argvlist = PyMem_NEW(char *, argc+1);
5225 + if (argvlist == NULL) {
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,
5240 + argvlist[argc] = NULL;
5242 + i = PyMapping_Size(env);
5245 + envlist = PyMem_NEW(char *, i + 1);
5246 + if (envlist == NULL) {
5251 + keys = PyMapping_Keys(env);
5252 + vals = PyMapping_Values(env);
5253 + if (!keys || !vals)
5255 + if (!PyList_Check(keys) || !PyList_Check(vals)) {
5256 + PyErr_SetString(PyExc_TypeError,
5257 + "execve(): env.keys() or env.values() is not a list");
5261 + for (pos = 0; pos < i; pos++) {
5265 + key = PyList_GetItem(keys, pos);
5266 + val = PyList_GetItem(vals, pos);
5272 + "s;execve() arg 3 contains a non-string key",
5276 + "s;execve() arg 3 contains a non-string value",
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) {
5286 + len = PyString_Size(key) + PyString_Size(val) + 2;
5287 + p = PyMem_NEW(char, len);
5292 + PyOS_snprintf(p, len, "%s=%s", k, v);
5293 + envlist[envc++] = p;
5294 +#if defined(PYOS_OS2)
5298 + envlist[envc] = 0;
5300 + execve(path, argvlist, envlist);
5302 + /* If we get here it's definitely an error */
5304 + (void) posix_error();
5307 + while (--envc >= 0)
5308 + PyMem_DEL(envlist[envc]);
5309 + PyMem_DEL(envlist);
5311 + free_string_array(argvlist, lastarg);
5318 +#endif /* HAVE_EXECV */
5322 +PyDoc_STRVAR(posix_spawnv__doc__,
5323 +"spawnv(mode, path, args)\n\n\
5324 +Execute the program 'path' in a new process.\n\
5326 + mode: mode of process creation\n\
5327 + path: path of executable file\n\
5328 + args: tuple or list of strings");
5331 +posix_spawnv(PyObject *self, PyObject *args)
5338 + Py_intptr_t spawnval;
5339 + PyObject *(*getitem)(PyObject *, Py_ssize_t);
5341 + /* spawnv has three arguments: (mode, path, argv), where
5342 + argv is a list or tuple of strings. */
5344 + if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
5345 + Py_FileSystemDefaultEncoding,
5348 + if (PyList_Check(argv)) {
5349 + argc = PyList_Size(argv);
5350 + getitem = PyList_GetItem;
5352 + else if (PyTuple_Check(argv)) {
5353 + argc = PyTuple_Size(argv);
5354 + getitem = PyTuple_GetItem;
5357 + PyErr_SetString(PyExc_TypeError,
5358 + "spawnv() arg 2 must be a tuple or list");
5363 + argvlist = PyMem_NEW(char *, argc+1);
5364 + if (argvlist == NULL) {
5366 + return PyErr_NoMemory();
5368 + for (i = 0; i < argc; i++) {
5369 + if (!PyArg_Parse((*getitem)(argv, i), "et",
5370 + Py_FileSystemDefaultEncoding,
5372 + free_string_array(argvlist, i);
5375 + "spawnv() arg 2 must contain only strings");
5380 + argvlist[argc] = NULL;
5382 +#if defined(PYOS_OS2) && defined(PYCC_GCC)
5383 + Py_BEGIN_ALLOW_THREADS
5384 + spawnval = spawnv(mode, path, argvlist);
5385 + Py_END_ALLOW_THREADS
5387 + if (mode == _OLD_P_OVERLAY)
5388 + mode = _P_OVERLAY;
5390 + Py_BEGIN_ALLOW_THREADS
5391 + spawnval = _spawnv(mode, path, argvlist);
5392 + Py_END_ALLOW_THREADS
5395 + free_string_array(argvlist, argc);
5398 + if (spawnval == -1)
5399 + return posix_error();
5401 +#if SIZEOF_LONG == SIZEOF_VOID_P
5402 + return Py_BuildValue("l", (long) spawnval);
5404 + return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
5409 +PyDoc_STRVAR(posix_spawnve__doc__,
5410 +"spawnve(mode, path, args, env)\n\n\
5411 +Execute the program 'path' in a new process.\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");
5419 +posix_spawnve(PyObject *self, PyObject *args)
5422 + PyObject *argv, *env;
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;
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. */
5436 + if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
5437 + Py_FileSystemDefaultEncoding,
5438 + &path, &argv, &env))
5440 + if (PyList_Check(argv)) {
5441 + argc = PyList_Size(argv);
5442 + getitem = PyList_GetItem;
5444 + else if (PyTuple_Check(argv)) {
5445 + argc = PyTuple_Size(argv);
5446 + getitem = PyTuple_GetItem;
5449 + PyErr_SetString(PyExc_TypeError,
5450 + "spawnve() arg 2 must be a tuple or list");
5453 + if (!PyMapping_Check(env)) {
5454 + PyErr_SetString(PyExc_TypeError,
5455 + "spawnve() arg 3 must be a mapping object");
5459 + argvlist = PyMem_NEW(char *, argc+1);
5460 + if (argvlist == NULL) {
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,
5475 + argvlist[argc] = NULL;
5477 + i = PyMapping_Size(env);
5480 + envlist = PyMem_NEW(char *, i + 1);
5481 + if (envlist == NULL) {
5486 + keys = PyMapping_Keys(env);
5487 + vals = PyMapping_Values(env);
5488 + if (!keys || !vals)
5490 + if (!PyList_Check(keys) || !PyList_Check(vals)) {
5491 + PyErr_SetString(PyExc_TypeError,
5492 + "spawnve(): env.keys() or env.values() is not a list");
5496 + for (pos = 0; pos < i; pos++) {
5500 + key = PyList_GetItem(keys, pos);
5501 + val = PyList_GetItem(vals, pos);
5507 + "s;spawnve() arg 3 contains a non-string key",
5511 + "s;spawnve() arg 3 contains a non-string value",
5516 + len = PyString_Size(key) + PyString_Size(val) + 2;
5517 + p = PyMem_NEW(char, len);
5522 + PyOS_snprintf(p, len, "%s=%s", k, v);
5523 + envlist[envc++] = p;
5525 + envlist[envc] = 0;
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
5532 + if (mode == _OLD_P_OVERLAY)
5533 + mode = _P_OVERLAY;
5535 + Py_BEGIN_ALLOW_THREADS
5536 + spawnval = _spawnve(mode, path, argvlist, envlist);
5537 + Py_END_ALLOW_THREADS
5540 + if (spawnval == -1)
5541 + (void) posix_error();
5543 +#if SIZEOF_LONG == SIZEOF_VOID_P
5544 + res = Py_BuildValue("l", (long) spawnval);
5546 + res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
5550 + while (--envc >= 0)
5551 + PyMem_DEL(envlist[envc]);
5552 + PyMem_DEL(envlist);
5554 + free_string_array(argvlist, lastarg);
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\
5569 + mode: mode of process creation\n\
5570 + file: executable file name\n\
5571 + args: tuple or list of strings");
5574 +posix_spawnvp(PyObject *self, PyObject *args)
5579 + int mode, i, argc;
5580 + Py_intptr_t spawnval;
5581 + PyObject *(*getitem)(PyObject *, Py_ssize_t);
5583 + /* spawnvp has three arguments: (mode, path, argv), where
5584 + argv is a list or tuple of strings. */
5586 + if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
5587 + Py_FileSystemDefaultEncoding,
5590 + if (PyList_Check(argv)) {
5591 + argc = PyList_Size(argv);
5592 + getitem = PyList_GetItem;
5594 + else if (PyTuple_Check(argv)) {
5595 + argc = PyTuple_Size(argv);
5596 + getitem = PyTuple_GetItem;
5599 + PyErr_SetString(PyExc_TypeError,
5600 + "spawnvp() arg 2 must be a tuple or list");
5605 + argvlist = PyMem_NEW(char *, argc+1);
5606 + if (argvlist == NULL) {
5608 + return PyErr_NoMemory();
5610 + for (i = 0; i < argc; i++) {
5611 + if (!PyArg_Parse((*getitem)(argv, i), "et",
5612 + Py_FileSystemDefaultEncoding,
5614 + free_string_array(argvlist, i);
5617 + "spawnvp() arg 2 must contain only strings");
5622 + argvlist[argc] = NULL;
5624 + Py_BEGIN_ALLOW_THREADS
5625 +#if defined(PYCC_GCC)
5626 + spawnval = spawnvp(mode, path, argvlist);
5628 + spawnval = _spawnvp(mode, path, argvlist);
5630 + Py_END_ALLOW_THREADS
5632 + free_string_array(argvlist, argc);
5635 + if (spawnval == -1)
5636 + return posix_error();
5638 + return Py_BuildValue("l", (long) spawnval);
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\
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");
5653 +posix_spawnvpe(PyObject *self, PyObject *args)
5656 + PyObject *argv, *env;
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);
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. */
5669 + if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5670 + Py_FileSystemDefaultEncoding,
5671 + &path, &argv, &env))
5673 + if (PyList_Check(argv)) {
5674 + argc = PyList_Size(argv);
5675 + getitem = PyList_GetItem;
5677 + else if (PyTuple_Check(argv)) {
5678 + argc = PyTuple_Size(argv);
5679 + getitem = PyTuple_GetItem;
5682 + PyErr_SetString(PyExc_TypeError,
5683 + "spawnvpe() arg 2 must be a tuple or list");
5686 + if (!PyMapping_Check(env)) {
5687 + PyErr_SetString(PyExc_TypeError,
5688 + "spawnvpe() arg 3 must be a mapping object");
5692 + argvlist = PyMem_NEW(char *, argc+1);
5693 + if (argvlist == NULL) {
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,
5708 + argvlist[argc] = NULL;
5710 + i = PyMapping_Size(env);
5713 + envlist = PyMem_NEW(char *, i + 1);
5714 + if (envlist == NULL) {
5719 + keys = PyMapping_Keys(env);
5720 + vals = PyMapping_Values(env);
5721 + if (!keys || !vals)
5723 + if (!PyList_Check(keys) || !PyList_Check(vals)) {
5724 + PyErr_SetString(PyExc_TypeError,
5725 + "spawnvpe(): env.keys() or env.values() is not a list");
5729 + for (pos = 0; pos < i; pos++) {
5733 + key = PyList_GetItem(keys, pos);
5734 + val = PyList_GetItem(vals, pos);
5740 + "s;spawnvpe() arg 3 contains a non-string key",
5744 + "s;spawnvpe() arg 3 contains a non-string value",
5749 + len = PyString_Size(key) + PyString_Size(val) + 2;
5750 + p = PyMem_NEW(char, len);
5755 + PyOS_snprintf(p, len, "%s=%s", k, v);
5756 + envlist[envc++] = p;
5758 + envlist[envc] = 0;
5760 + Py_BEGIN_ALLOW_THREADS
5761 +#if defined(PYCC_GCC)
5762 + spawnval = spawnvpe(mode, path, argvlist, envlist);
5764 + spawnval = _spawnvpe(mode, path, argvlist, envlist);
5766 + Py_END_ALLOW_THREADS
5768 + if (spawnval == -1)
5769 + (void) posix_error();
5771 + res = Py_BuildValue("l", (long) spawnval);
5774 + while (--envc >= 0)
5775 + PyMem_DEL(envlist[envc]);
5776 + PyMem_DEL(envlist);
5778 + free_string_array(argvlist, lastarg);
5785 +#endif /* PYOS_OS2 */
5786 +#endif /* HAVE_SPAWNV */
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\
5794 +Return 0 to child process and PID of child to parent process.");
5797 +posix_fork1(PyObject *self, PyObject *noargs)
5799 + int pid = fork1();
5801 + return posix_error();
5803 + return PyInt_FromLong((long)pid);
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.");
5815 +posix_fork(PyObject *self, PyObject *noargs)
5819 + return posix_error();
5822 + return PyInt_FromLong((long)pid);
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
5832 +#define DEV_PTY_FILE "/dev/ptmx"
5835 +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
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>
5846 +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
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");
5854 +posix_openpty(PyObject *self, PyObject *noargs)
5856 + int master_fd, slave_fd;
5857 +#ifndef HAVE_OPENPTY
5858 + char * slave_name;
5860 +#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
5861 + PyOS_sighandler_t sig_saved;
5863 + extern char *ptsname(int fildes);
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();
5875 + slave_fd = open(slave_name, O_RDWR);
5877 + return posix_error();
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();
5888 + /* unlock slave */
5889 + if (unlockpt(master_fd) < 0) {
5890 + PyOS_setsig(SIGCHLD, sig_saved);
5891 + return posix_error();
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 */
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 */
5904 + ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
5905 +#endif /* __hpux */
5906 +#endif /* HAVE_CYGWIN */
5907 +#endif /* HAVE_OPENPTY */
5909 + return Py_BuildValue("(ii)", master_fd, slave_fd);
5912 +#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
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");
5922 +posix_forkpty(PyObject *self, PyObject *noargs)
5924 + int master_fd = -1, pid;
5926 + pid = forkpty(&master_fd, NULL, NULL, NULL);
5928 + return posix_error();
5931 + return Py_BuildValue("(ii)", pid, master_fd);
5935 +#ifdef HAVE_GETEGID
5936 +PyDoc_STRVAR(posix_getegid__doc__,
5937 +"getegid() -> egid\n\n\
5938 +Return the current process's effective group id.");
5941 +posix_getegid(PyObject *self, PyObject *noargs)
5943 + return PyInt_FromLong((long)getegid());
5948 +#ifdef HAVE_GETEUID
5949 +PyDoc_STRVAR(posix_geteuid__doc__,
5950 +"geteuid() -> euid\n\n\
5951 +Return the current process's effective user id.");
5954 +posix_geteuid(PyObject *self, PyObject *noargs)
5956 + return PyInt_FromLong((long)geteuid());
5962 +PyDoc_STRVAR(posix_getgid__doc__,
5963 +"getgid() -> gid\n\n\
5964 +Return the current process's group id.");
5967 +posix_getgid(PyObject *self, PyObject *noargs)
5969 + return PyInt_FromLong((long)getgid());
5974 +PyDoc_STRVAR(posix_getpid__doc__,
5975 +"getpid() -> pid\n\n\
5976 +Return the current process id");
5979 +posix_getpid(PyObject *self, PyObject *noargs)
5981 + return PyInt_FromLong((long)getpid());
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.");
5991 +posix_getgroups(PyObject *self, PyObject *noargs)
5993 + PyObject *result = NULL;
5996 +#define MAX_GROUPS NGROUPS_MAX
5998 + /* defined to be 16 on Solaris7, so this should be a small number */
5999 +#define MAX_GROUPS 64
6001 + gid_t grouplist[MAX_GROUPS];
6004 + n = getgroups(MAX_GROUPS, grouplist);
6008 + result = PyList_New(n);
6009 + if (result != NULL) {
6011 + for (i = 0; i < n; ++i) {
6012 + PyObject *o = PyInt_FromLong((long)grouplist[i]);
6014 + Py_DECREF(result);
6018 + PyList_SET_ITEM(result, i, o);
6027 +#ifdef HAVE_GETPGID
6028 +PyDoc_STRVAR(posix_getpgid__doc__,
6029 +"getpgid(pid) -> pgid\n\n\
6030 +Call the system call getpgid().");
6033 +posix_getpgid(PyObject *self, PyObject *args)
6036 + if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
6038 + pgid = getpgid(pid);
6040 + return posix_error();
6041 + return PyInt_FromLong((long)pgid);
6043 +#endif /* HAVE_GETPGID */
6046 +#ifdef HAVE_GETPGRP
6047 +PyDoc_STRVAR(posix_getpgrp__doc__,
6048 +"getpgrp() -> pgrp\n\n\
6049 +Return the current process group id.");
6052 +posix_getpgrp(PyObject *self, PyObject *noargs)
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 */
6060 +#endif /* HAVE_GETPGRP */
6063 +#ifdef HAVE_SETPGRP
6064 +PyDoc_STRVAR(posix_setpgrp__doc__,
6066 +Make this process a session leader.");
6069 +posix_setpgrp(PyObject *self, PyObject *noargs)
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);
6081 +#endif /* HAVE_SETPGRP */
6083 +#ifdef HAVE_GETPPID
6084 +PyDoc_STRVAR(posix_getppid__doc__,
6085 +"getppid() -> ppid\n\n\
6086 +Return the parent's process id.");
6089 +posix_getppid(PyObject *self, PyObject *noargs)
6091 + return PyInt_FromLong((long)getppid());
6096 +#ifdef HAVE_GETLOGIN
6097 +PyDoc_STRVAR(posix_getlogin__doc__,
6098 +"getlogin() -> string\n\n\
6099 +Return the actual login name.");
6102 +posix_getlogin(PyObject *self, PyObject *noargs)
6104 + PyObject *result = NULL;
6106 + int old_errno = errno;
6109 + name = getlogin();
6110 + if (name == NULL) {
6114 + PyErr_SetString(PyExc_OSError,
6115 + "unable to determine login name");
6118 + result = PyString_FromString(name);
6119 + errno = old_errno;
6126 +PyDoc_STRVAR(posix_getuid__doc__,
6127 +"getuid() -> uid\n\n\
6128 +Return the current process's user id.");
6131 +posix_getuid(PyObject *self, PyObject *noargs)
6133 + return PyInt_FromLong((long)getuid());
6139 +PyDoc_STRVAR(posix_kill__doc__,
6140 +"kill(pid, sig)\n\n\
6141 +Kill a process with a signal.");
6144 +posix_kill(PyObject *self, PyObject *args)
6147 + if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
6149 +#if defined(PYOS_OS2) && !defined(PYCC_GCC)
6150 + if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6152 + if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
6153 + return os2_error(rc);
6155 + } else if (sig == XCPT_SIGNAL_KILLPROC) {
6157 + if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
6158 + return os2_error(rc);
6161 + return NULL; /* Unrecognized Signal Requested */
6163 + if (kill(pid, sig) == -1)
6164 + return posix_error();
6166 + Py_INCREF(Py_None);
6172 +PyDoc_STRVAR(posix_killpg__doc__,
6173 +"killpg(pgid, sig)\n\n\
6174 +Kill a process group with a signal.");
6177 +posix_killpg(PyObject *self, PyObject *args)
6180 + if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
6182 + if (killpg(pgid, sig) == -1)
6183 + return posix_error();
6184 + Py_INCREF(Py_None);
6191 +#ifdef HAVE_SYS_LOCK_H
6192 +#include <sys/lock.h>
6195 +PyDoc_STRVAR(posix_plock__doc__,
6197 +Lock program segments into memory.");
6200 +posix_plock(PyObject *self, PyObject *args)
6203 + if (!PyArg_ParseTuple(args, "i:plock", &op))
6205 + if (plock(op) == -1)
6206 + return posix_error();
6207 + Py_INCREF(Py_None);
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.");
6218 +#if defined(PYOS_OS2)
6219 +#if defined(PYCC_VACPP)
6221 +async_system(const char *command)
6223 + char errormsg[256], args[1024];
6224 + RESULTCODES rcodes;
6227 + char *shell = getenv("COMSPEC");
6231 + /* avoid overflowing the argument buffer */
6232 + if (strlen(shell) + 3 + strlen(command) >= 1024)
6233 + return ERROR_NOT_ENOUGH_MEMORY
6236 + strcat(args, shell);
6237 + strcat(args, "/c ");
6238 + strcat(args, command);
6240 + /* execute asynchronously, inheriting the environment */
6241 + rc = DosExecPgm(errormsg,
6252 +popen(const char *command, const char *mode, int pipesize, int *err)
6258 + /* mode determines which of stdin or stdout is reconnected to
6259 + * the pipe to the child
6261 + if (strchr(mode, 'r') != NULL) {
6262 + tgt_fd = 1; /* stdout */
6263 + } else if (strchr(mode, 'w')) {
6264 + tgt_fd = 0; /* stdin */
6266 + *err = ERROR_INVALID_ACCESS;
6270 + /* setup the pipe */
6271 + if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
6276 + /* prevent other threads accessing stdio */
6277 + DosEnterCritSec();
6279 + /* reconnect stdio and execute child */
6280 + oldfd = dup(tgtfd);
6282 + if (dup2(pipeh[tgtfd], tgtfd) == 0) {
6283 + DosClose(pipeh[tgtfd]);
6284 + rc = async_system(command);
6287 + /* restore stdio */
6288 + dup2(oldfd, tgtfd);
6291 + /* allow other threads access to stdio */
6294 + /* if execution of child was successful return file stream */
6295 + if (rc == NO_ERROR)
6296 + return fdopen(pipeh[1 - tgtfd], mode);
6298 + DosClose(pipeh[1 - tgtfd]);
6305 +posix_popen(PyObject *self, PyObject *args)
6309 + int err, bufsize = -1;
6312 + if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
6314 + Py_BEGIN_ALLOW_THREADS
6315 + fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
6316 + Py_END_ALLOW_THREADS
6318 + return os2_error(err);
6320 + f = PyFile_FromFile(fp, name, mode, fclose);
6322 + PyFile_SetBufSize(f, bufsize);
6326 +#elif defined(PYCC_GCC)
6328 +/* standard posix version of popen() support */
6330 +posix_popen(PyObject *self, PyObject *args)
6337 + if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
6339 + Py_BEGIN_ALLOW_THREADS
6340 + fp = popen(name, mode);
6341 + Py_END_ALLOW_THREADS
6343 + return posix_error();
6344 + f = PyFile_FromFile(fp, name, mode, pclose);
6346 + PyFile_SetBufSize(f, bufsize);
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
6356 +/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
6362 +static PyObject *_PyPopen(char *, int, int, int);
6363 +static int _PyPclose(FILE *file);
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.
6370 +static PyObject *_PyPopenProcs = NULL;
6372 +/* os2emx version of popen2()
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.
6379 +os2emx_popen2(PyObject *self, PyObject *args)
6387 + if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
6392 + else if (*mode != 'b') {
6393 + PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6398 + f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
6404 + * Variation on os2emx.popen2
6406 + * The result of this function is 3 pipes - the process's stdin,
6407 + * stdout and stderr
6411 +os2emx_popen3(PyObject *self, PyObject *args)
6419 + if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
6424 + else if (*mode != 'b') {
6425 + PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6430 + f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
6436 + * Variation on os2emx.popen2
6438 + * The result of this function is 2 pipes - the processes stdin,
6439 + * and stdout+stderr combined as a single pipe.
6443 +os2emx_popen4(PyObject *self, PyObject *args)
6451 + if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
6456 + else if (*mode != 'b') {
6457 + PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
6462 + f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
6467 +/* a couple of structures for convenient handling of multiple
6468 + * file handles and pipes
6482 +/* The following code is derived from the win32 code */
6485 +_PyPopen(char *cmdstring, int mode, int n, int bufsize)
6487 + struct file_ref stdio[3];
6488 + struct pipe_ref p_fd[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];
6494 + /* file modes for subsequent fdopen's on pipe handles */
6495 + if (mode == O_TEXT)
6506 + /* prepare shell references */
6507 + if ((shell = getenv("EMXSHELL")) == NULL)
6508 + if ((shell = getenv("COMSPEC")) == NULL)
6511 + return posix_error();
6514 + sh_name = _getname(shell);
6515 + if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
6520 + /* save current stdio fds + their flags, and set not inheritable */
6522 + while (pipe_err >= 0 && i < 3)
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);
6531 + /* didn't get them all saved - clean up and bail out */
6532 + int saved_err = errno;
6535 + close(stdio[i].handle);
6537 + errno = saved_err;
6538 + return posix_error();
6541 + /* create pipe ends */
6546 + while ((pipe_err == 0) && (i < file_count))
6547 + pipe_err = pipe((int *)&p_fd[i++]);
6550 + /* didn't get them all made - clean up and bail out */
6553 + close(p_fd[i].wr);
6554 + close(p_fd[i].rd);
6557 + return posix_error();
6560 + /* change the actual standard IO streams over temporarily,
6561 + * making the retained pipe ends non-inheritable
6566 + if (dup2(p_fd[0].rd, 0) == 0)
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)
6573 + close(p_fd[0].wr);
6583 + if (pipe_err == 0)
6585 + if (dup2(p_fd[1].wr, 1) == 1)
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)
6592 + close(p_fd[1].rd);
6602 + /* - stderr, as required */
6603 + if (pipe_err == 0)
6608 + if (dup2(p_fd[2].wr, 2) == 2)
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)
6615 + close(p_fd[2].rd);
6628 + if (dup2(1, 2) != 2)
6636 + /* spawn the child process */
6637 + if (pipe_err == 0)
6639 + pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
6640 + if (pipe_pid == -1)
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
6651 + for (i = 0; i < file_count; i++)
6652 + p_s[i]->_pid = pipe_pid;
6656 + /* reset standard IO to normal */
6657 + for (i = 0; i < 3; i++)
6659 + dup2(stdio[i].handle, i);
6660 + fcntl(i, F_SETFD, stdio[i].flags);
6661 + close(stdio[i].handle);
6664 + /* if any remnant problems, clean up and bail out */
6667 + for (i = 0; i < 3; i++)
6669 + close(p_fd[i].rd);
6670 + close(p_fd[i].wr);
6673 + return posix_error_with_filename(cmdstring);
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);
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]);
6688 + f = PyTuple_Pack(2, p_f[0], p_f[1]);
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.
6701 + if (!_PyPopenProcs)
6703 + _PyPopenProcs = PyDict_New();
6706 + if (_PyPopenProcs)
6708 + PyObject *procObj, *pidObj, *intObj, *fileObj[3];
6711 + fileObj[0] = fileObj[1] = fileObj[2] = NULL;
6712 + ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
6714 + procObj = PyList_New(2);
6715 + pidObj = PyInt_FromLong((long) pipe_pid);
6716 + intObj = PyInt_FromLong((long) file_count);
6718 + if (procObj && pidObj && intObj)
6720 + PyList_SetItem(procObj, 0, pidObj);
6721 + PyList_SetItem(procObj, 1, intObj);
6723 + fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
6726 + ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
6730 + fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
6733 + ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
6737 + if (file_count >= 3)
6739 + fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
6742 + ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
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]))
6752 + /* Something failed - remove any dictionary
6753 + * entries that did make it.
6755 + if (!ins_rc[0] && fileObj[0])
6757 + PyDict_DelItem(_PyPopenProcs,
6760 + if (!ins_rc[1] && fileObj[1])
6762 + PyDict_DelItem(_PyPopenProcs,
6765 + if (!ins_rc[2] && fileObj[2])
6767 + PyDict_DelItem(_PyPopenProcs,
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.
6778 + Py_XDECREF(procObj);
6779 + Py_XDECREF(fileObj[0]);
6780 + Py_XDECREF(fileObj[1]);
6781 + Py_XDECREF(fileObj[2]);
6784 + /* Child is launched. */
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.
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.
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.
6810 + * NOTE: This function is currently called with the GIL released.
6811 + * hence we use the GILState API to manage our state.
6814 +static int _PyPclose(FILE *file)
6819 + PyObject *procObj, *pidObj, *intObj, *fileObj;
6822 + PyGILState_STATE state;
6825 + /* Close the file handle first, to ensure it can't block the
6826 + * child from exiting if it's the last handle.
6828 + result = fclose(file);
6831 + state = PyGILState_Ensure();
6833 + if (_PyPopenProcs)
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)
6841 + pipe_pid = (int) PyInt_AsLong(pidObj);
6842 + file_count = (int) PyInt_AsLong(intObj);
6844 + if (file_count > 1)
6846 + /* Still other files referencing process */
6848 + PyList_SetItem(procObj,1,
6849 + PyInt_FromLong((long) file_count));
6853 + /* Last file for this process */
6854 + if (result != EOF &&
6855 + waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
6857 + /* extract exit status */
6858 + if (WIFEXITED(exit_code))
6860 + result = WEXITSTATUS(exit_code);
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.
6880 + /* Remove this file pointer from dictionary */
6881 + PyDict_DelItem(_PyPopenProcs, fileObj);
6883 + if (PyDict_Size(_PyPopenProcs) == 0)
6885 + Py_DECREF(_PyPopenProcs);
6886 + _PyPopenProcs = NULL;
6889 + } /* if object retrieval ok */
6891 + Py_XDECREF(fileObj);
6892 + } /* if _PyPopenProcs */
6895 + PyGILState_Release(state);
6900 +#endif /* PYCC_??? */
6902 +#elif defined(MS_WINDOWS)
6905 + * Portable 'popen' replacement for Win32.
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>.
6912 +#include <malloc.h>
6916 +/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
6922 +static PyObject *_PyPopen(char *, int, int);
6923 +static int _PyPclose(FILE *file);
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.
6930 +static PyObject *_PyPopenProcs = NULL;
6933 +/* popen that works from a GUI.
6935 + * The result of this function is a pipe (file) connected to the
6936 + * processes stdin or stdout, depending on the requested mode.
6940 +posix_popen(PyObject *self, PyObject *args)
6948 + if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
6953 + else if (*mode != 'w') {
6954 + PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
6959 + if (bufsize != -1) {
6960 + PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
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);
6969 + f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
6974 +/* Variation on win32pipe.popen
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.
6981 +win32_popen2(PyObject *self, PyObject *args)
6989 + if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
6994 + else if (*mode != 'b') {
6995 + PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
7000 + if (bufsize != -1) {
7001 + PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
7005 + f = _PyPopen(cmdstring, tm, POPEN_2);
7011 + * Variation on <om win32pipe.popen>
7013 + * The result of this function is 3 pipes - the process's stdin,
7014 + * stdout and stderr
7018 +win32_popen3(PyObject *self, PyObject *args)
7026 + if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
7031 + else if (*mode != 'b') {
7032 + PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
7037 + if (bufsize != -1) {
7038 + PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
7042 + f = _PyPopen(cmdstring, tm, POPEN_3);
7048 + * Variation on win32pipe.popen
7050 + * The result of this function is 2 pipes - the processes stdin,
7051 + * and stdout+stderr combined as a single pipe.
7055 +win32_popen4(PyObject *self, PyObject *args)
7063 + if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
7068 + else if (*mode != 'b') {
7069 + PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
7074 + if (bufsize != -1) {
7075 + PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
7079 + f = _PyPopen(cmdstring, tm, POPEN_4);
7085 +_PyPopenCreateProcess(char *cmdstring,
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";
7099 + if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
7102 + s1 = (char *)alloca(i);
7103 + if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
7104 + /* x < i, so x fits into an integer */
7107 + /* Explicitly check if we are using COMMAND.COM. If we are
7108 + * then use the w9xpopen hack.
7110 + comshell = s1 + x;
7111 + while (comshell >= s1 && *comshell != '\\')
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);
7125 + * Oh gag, we're on Win9x or using COMMAND.COM. Use
7126 + * the workaround listed in KB: Q150956
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)
7134 + modulepath[x] = '\0';
7135 + /* Create the full-name to w9xpopen, so we can test it exists */
7136 + strncat(modulepath,
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
7145 + strncpy(modulepath,
7146 + Py_GetExecPrefix(),
7148 + modulepath[mplen-1] = '\0';
7149 + if (modulepath[strlen(modulepath)-1] != '\\')
7150 + strcat(modulepath, "\\");
7151 + strncat(modulepath,
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 ;-)
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 "
7169 + x = i + strlen(s3) + strlen(cmdstring) + 1 +
7170 + strlen(modulepath) +
7171 + strlen(szConsoleSpawn) + 1;
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.
7188 + /* Not passing CREATE_NEW_CONSOLE has been known to
7189 + cause random failures on win9x. Specifically a
7191 + "Your program accessed mem currently in use at xxx"
7192 + and a hopeful warning about the stability of your
7194 + Cost is Ctrl+C wont kill children, but anyone
7195 + who cares can have a go!
7197 + dwProcessFlags |= CREATE_NEW_CONSOLE;
7201 + /* Could be an else here to try cmd.exe / command.com in the path
7202 + Now we'll just error out.. */
7204 + PyErr_SetString(PyExc_RuntimeError,
7205 + "Cannot locate a COMSPEC environment variable to "
7206 + "use as the shell");
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;
7218 + if (CreateProcess(NULL,
7228 + /* Close the handles now so anyone waiting is woken. */
7229 + CloseHandle(piProcInfo.hThread);
7231 + /* Return process handle */
7232 + *hProcess = piProcInfo.hProcess;
7235 + win32_error("CreateProcess", s2);
7239 +/* The following code is based off of KB: Q190351 */
7242 +_PyPopen(char *cmdstring, int mode, int n)
7244 + HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
7245 + hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
7246 + hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
7248 + SECURITY_ATTRIBUTES saAttr;
7250 + int fd1, fd2, fd3;
7251 + FILE *f1, *f2, *f3;
7255 + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
7256 + saAttr.bInheritHandle = TRUE;
7257 + saAttr.lpSecurityDescriptor = NULL;
7259 + if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
7260 + return win32_error("CreatePipe", NULL);
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,
7269 + DUPLICATE_SAME_ACCESS);
7271 + return win32_error("DuplicateHandle", NULL);
7273 + /* Close the inheritable version of ChildStdin
7274 + that we're using. */
7275 + CloseHandle(hChildStdinWr);
7277 + if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
7278 + return win32_error("CreatePipe", NULL);
7280 + fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
7281 + GetCurrentProcess(), &hChildStdoutRdDup, 0,
7282 + FALSE, DUPLICATE_SAME_ACCESS);
7284 + return win32_error("DuplicateHandle", NULL);
7286 + /* Close the inheritable version of ChildStdout
7287 + that we're using. */
7288 + CloseHandle(hChildStdoutRd);
7290 + if (n != POPEN_4) {
7291 + if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
7292 + return win32_error("CreatePipe", NULL);
7293 + fSuccess = DuplicateHandle(GetCurrentProcess(),
7295 + GetCurrentProcess(),
7296 + &hChildStderrRdDup, 0,
7297 + FALSE, DUPLICATE_SAME_ACCESS);
7299 + return win32_error("DuplicateHandle", NULL);
7300 + /* Close the inheritable version of ChildStdErr that we're using. */
7301 + CloseHandle(hChildStderrRd);
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);
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);
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);
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);
7358 + PyObject *p1, *p2;
7360 + if (mode & _O_TEXT) {
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);
7378 + CloseHandle(hChildStderrRdDup);
7380 + f = PyTuple_Pack(2,p1,p2);
7390 + PyObject *p1, *p2, *p3;
7392 + if (mode & _O_TEXT) {
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);
7421 + if (n == POPEN_4) {
7422 + if (!_PyPopenCreateProcess(cmdstring,
7430 + if (!_PyPopenCreateProcess(cmdstring,
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.
7449 + if (!_PyPopenProcs) {
7450 + _PyPopenProcs = PyDict_New();
7453 + if (_PyPopenProcs) {
7454 + PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
7457 + fileObj[0] = fileObj[1] = fileObj[2] = NULL;
7458 + ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
7460 + procObj = PyList_New(2);
7461 + hProcessObj = PyLong_FromVoidPtr(hProcess);
7462 + intObj = PyInt_FromLong(file_count);
7464 + if (procObj && hProcessObj && intObj) {
7465 + PyList_SetItem(procObj,0,hProcessObj);
7466 + PyList_SetItem(procObj,1,intObj);
7468 + fileObj[0] = PyLong_FromVoidPtr(f1);
7470 + ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
7474 + if (file_count >= 2) {
7475 + fileObj[1] = PyLong_FromVoidPtr(f2);
7477 + ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
7482 + if (file_count >= 3) {
7483 + fileObj[2] = PyLong_FromVoidPtr(f3);
7485 + ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
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.
7497 + if (!ins_rc[0] && fileObj[0]) {
7498 + PyDict_DelItem(_PyPopenProcs,
7501 + if (!ins_rc[1] && fileObj[1]) {
7502 + PyDict_DelItem(_PyPopenProcs,
7505 + if (!ins_rc[2] && fileObj[2]) {
7506 + PyDict_DelItem(_PyPopenProcs,
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.
7517 + Py_XDECREF(procObj);
7518 + Py_XDECREF(fileObj[0]);
7519 + Py_XDECREF(fileObj[1]);
7520 + Py_XDECREF(fileObj[2]);
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. */
7529 + if (!CloseHandle(hChildStdinRd))
7530 + return win32_error("CloseHandle", NULL);
7532 + if (!CloseHandle(hChildStdoutWr))
7533 + return win32_error("CloseHandle", NULL);
7535 + if ((n != 4) && (!CloseHandle(hChildStderrWr)))
7536 + return win32_error("CloseHandle", NULL);
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.
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.
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.
7563 + * NOTE: This function is currently called with the GIL released.
7564 + * hence we use the GILState API to manage our state.
7567 +static int _PyPclose(FILE *file)
7572 + PyObject *procObj, *hProcessObj, *intObj, *fileObj;
7575 + PyGILState_STATE state;
7578 + /* Close the file handle first, to ensure it can't block the
7579 + * child from exiting if it's the last handle.
7581 + result = fclose(file);
7583 + state = PyGILState_Ensure();
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) {
7592 + hProcess = PyLong_AsVoidPtr(hProcessObj);
7593 + file_count = PyInt_AsLong(intObj);
7595 + if (file_count > 1) {
7596 + /* Still other files referencing process */
7598 + PyList_SetItem(procObj,1,
7599 + PyInt_FromLong(file_count));
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.
7608 + result = exit_code;
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.
7616 + if (result != EOF) {
7617 + /* If the error wasn't from the fclose(), then
7618 + * set errno for the file object error handling.
7620 + errno = GetLastError();
7625 + /* Free up the native handle at this point */
7626 + CloseHandle(hProcess);
7629 + /* Remove this file pointer from dictionary */
7630 + PyDict_DelItem(_PyPopenProcs, fileObj);
7632 + if (PyDict_Size(_PyPopenProcs) == 0) {
7633 + Py_DECREF(_PyPopenProcs);
7634 + _PyPopenProcs = NULL;
7637 + } /* if object retrieval ok */
7639 + Py_XDECREF(fileObj);
7640 + } /* if _PyPopenProcs */
7643 + PyGILState_Release(state);
7648 +#else /* which OS? */
7650 +posix_popen(PyObject *self, PyObject *args)
7657 + if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
7659 + /* Strip mode of binary or text modifiers */
7660 + if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
7662 + else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
7664 + Py_BEGIN_ALLOW_THREADS
7665 + fp = popen(name, mode);
7666 + Py_END_ALLOW_THREADS
7668 + return posix_error();
7669 + f = PyFile_FromFile(fp, name, mode, pclose);
7671 + PyFile_SetBufSize(f, bufsize);
7675 +#endif /* PYOS_??? */
7676 +#endif /* HAVE_POPEN */
7680 +PyDoc_STRVAR(posix_setuid__doc__,
7682 +Set the current process's user id.");
7685 +posix_setuid(PyObject *self, PyObject *args)
7688 + if (!PyArg_ParseTuple(args, "i:setuid", &uid))
7690 + if (setuid(uid) < 0)
7691 + return posix_error();
7692 + Py_INCREF(Py_None);
7695 +#endif /* HAVE_SETUID */
7698 +#ifdef HAVE_SETEUID
7699 +PyDoc_STRVAR(posix_seteuid__doc__,
7701 +Set the current process's effective user id.");
7704 +posix_seteuid (PyObject *self, PyObject *args)
7707 + if (!PyArg_ParseTuple(args, "i", &euid)) {
7709 + } else if (seteuid(euid) < 0) {
7710 + return posix_error();
7712 + Py_INCREF(Py_None);
7716 +#endif /* HAVE_SETEUID */
7718 +#ifdef HAVE_SETEGID
7719 +PyDoc_STRVAR(posix_setegid__doc__,
7721 +Set the current process's effective group id.");
7724 +posix_setegid (PyObject *self, PyObject *args)
7727 + if (!PyArg_ParseTuple(args, "i", &egid)) {
7729 + } else if (setegid(egid) < 0) {
7730 + return posix_error();
7732 + Py_INCREF(Py_None);
7736 +#endif /* HAVE_SETEGID */
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.");
7744 +posix_setreuid (PyObject *self, PyObject *args)
7747 + if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
7749 + } else if (setreuid(ruid, euid) < 0) {
7750 + return posix_error();
7752 + Py_INCREF(Py_None);
7756 +#endif /* HAVE_SETREUID */
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.");
7764 +posix_setregid (PyObject *self, PyObject *args)
7767 + if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
7769 + } else if (setregid(rgid, egid) < 0) {
7770 + return posix_error();
7772 + Py_INCREF(Py_None);
7776 +#endif /* HAVE_SETREGID */
7779 +PyDoc_STRVAR(posix_setgid__doc__,
7781 +Set the current process's group id.");
7784 +posix_setgid(PyObject *self, PyObject *args)
7787 + if (!PyArg_ParseTuple(args, "i:setgid", &gid))
7789 + if (setgid(gid) < 0)
7790 + return posix_error();
7791 + Py_INCREF(Py_None);
7794 +#endif /* HAVE_SETGID */
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.");
7802 +posix_setgroups(PyObject *self, PyObject *groups)
7805 + gid_t grouplist[MAX_GROUPS];
7807 + if (!PySequence_Check(groups)) {
7808 + PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7811 + len = PySequence_Size(groups);
7812 + if (len > MAX_GROUPS) {
7813 + PyErr_SetString(PyExc_ValueError, "too many groups");
7816 + for(i = 0; i < len; i++) {
7818 + elem = PySequence_GetItem(groups, i);
7821 + if (!PyInt_Check(elem)) {
7822 + if (!PyLong_Check(elem)) {
7823 + PyErr_SetString(PyExc_TypeError,
7824 + "groups must be integers");
7828 + unsigned long x = PyLong_AsUnsignedLong(elem);
7829 + if (PyErr_Occurred()) {
7830 + PyErr_SetString(PyExc_TypeError,
7831 + "group id too big");
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");
7845 + long x = PyInt_AsLong(elem);
7847 + if (grouplist[i] != x) {
7848 + PyErr_SetString(PyExc_TypeError,
7849 + "group id too big");
7857 + if (setgroups(len, grouplist) < 0)
7858 + return posix_error();
7859 + Py_INCREF(Py_None);
7862 +#endif /* HAVE_SETGROUPS */
7864 +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7866 +wait_helper(int pid, int status, struct rusage *ru)
7869 + static PyObject *struct_rusage;
7872 + return posix_error();
7874 + if (struct_rusage == NULL) {
7875 + PyObject *m = PyImport_ImportModule("resource");
7878 + struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
7880 + if (struct_rusage == NULL)
7884 + /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7885 + result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7890 +#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
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);
7915 + if (PyErr_Occurred()) {
7916 + Py_DECREF(result);
7920 + return Py_BuildValue("iiN", pid, status, result);
7922 +#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7925 +PyDoc_STRVAR(posix_wait3__doc__,
7926 +"wait3(options) -> (pid, status, rusage)\n\n\
7927 +Wait for completion of a child process.");
7930 +posix_wait3(PyObject *self, PyObject *args)
7935 + WAIT_STATUS_INT(status) = 0;
7937 + if (!PyArg_ParseTuple(args, "i:wait3", &options))
7940 + Py_BEGIN_ALLOW_THREADS
7941 + pid = wait3(&status, options, &ru);
7942 + Py_END_ALLOW_THREADS
7944 + return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
7946 +#endif /* HAVE_WAIT3 */
7949 +PyDoc_STRVAR(posix_wait4__doc__,
7950 +"wait4(pid, options) -> (pid, status, rusage)\n\n\
7951 +Wait for completion of a given child process.");
7954 +posix_wait4(PyObject *self, PyObject *args)
7959 + WAIT_STATUS_INT(status) = 0;
7961 + if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
7964 + Py_BEGIN_ALLOW_THREADS
7965 + pid = wait4(pid, &status, options, &ru);
7966 + Py_END_ALLOW_THREADS
7968 + return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
7970 +#endif /* HAVE_WAIT4 */
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.");
7978 +posix_waitpid(PyObject *self, PyObject *args)
7982 + WAIT_STATUS_INT(status) = 0;
7984 + if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
7986 + Py_BEGIN_ALLOW_THREADS
7987 + pid = waitpid(pid, &status, options);
7988 + Py_END_ALLOW_THREADS
7990 + return posix_error();
7992 + return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
7995 +#elif defined(HAVE_CWAIT)
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.");
8003 +posix_waitpid(PyObject *self, PyObject *args)
8006 + int status, options;
8008 + if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
8010 + Py_BEGIN_ALLOW_THREADS
8011 + pid = _cwait(&status, pid, options);
8012 + Py_END_ALLOW_THREADS
8014 + return posix_error();
8016 + /* shift the status left a byte so this is more like the POSIX waitpid */
8017 + return Py_BuildValue("ii", pid, status << 8);
8019 +#endif /* HAVE_WAITPID || HAVE_CWAIT */
8022 +PyDoc_STRVAR(posix_wait__doc__,
8023 +"wait() -> (pid, status)\n\n\
8024 +Wait for completion of a child process.");
8027 +posix_wait(PyObject *self, PyObject *noargs)
8031 + WAIT_STATUS_INT(status) = 0;
8033 + Py_BEGIN_ALLOW_THREADS
8034 + pid = wait(&status);
8035 + Py_END_ALLOW_THREADS
8037 + return posix_error();
8039 + return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
8044 +PyDoc_STRVAR(posix_lstat__doc__,
8045 +"lstat(path) -> stat result\n\n\
8046 +Like stat(path), but do not follow symbolic links.");
8049 +posix_lstat(PyObject *self, PyObject *args)
8052 + return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
8053 +#else /* !HAVE_LSTAT */
8055 + return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
8057 + return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
8059 +#endif /* !HAVE_LSTAT */
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.");
8069 +posix_readlink(PyObject *self, PyObject *args)
8071 + char buf[MAXPATHLEN];
8074 + if (!PyArg_ParseTuple(args, "s:readlink", &path))
8076 + Py_BEGIN_ALLOW_THREADS
8077 + n = readlink(path, buf, (int) sizeof buf);
8078 + Py_END_ALLOW_THREADS
8080 + return posix_error_with_filename(path);
8081 + return PyString_FromStringAndSize(buf, n);
8083 +#endif /* HAVE_READLINK */
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.");
8092 +posix_symlink(PyObject *self, PyObject *args)
8094 + return posix_2str(args, "etet:symlink", symlink);
8096 +#endif /* HAVE_SYMLINK */
8101 +#define HZ 60 /* Universal constant :-) */
8104 +#if defined(PYCC_VACPP) && defined(PYOS_OS2)
8106 +system_uptime(void)
8110 + Py_BEGIN_ALLOW_THREADS
8111 + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
8112 + Py_END_ALLOW_THREADS
8118 +posix_times(PyObject *self, PyObject *noargs)
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);
8128 +#else /* not OS2 */
8130 +posix_times(PyObject *self, PyObject *noargs)
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,
8145 +#endif /* not OS2 */
8146 +#endif /* HAVE_TIMES */
8150 +#define HAVE_TIMES /* so the method table will pick it up */
8152 +posix_times(PyObject *self, PyObject *noargs)
8154 + FILETIME create, exit, kernel, user;
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.
8163 + return Py_BuildValue(
8165 + (double)(kernel.dwHighDateTime*429.4967296 +
8166 + kernel.dwLowDateTime*1e-7),
8167 + (double)(user.dwHighDateTime*429.4967296 +
8168 + user.dwLowDateTime*1e-7),
8173 +#endif /* MS_WINDOWS */
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.");
8183 +PyDoc_STRVAR(posix_getsid__doc__,
8184 +"getsid(pid) -> sid\n\n\
8185 +Call the system call getsid().");
8188 +posix_getsid(PyObject *self, PyObject *args)
8191 + if (!PyArg_ParseTuple(args, "i:getsid", &pid))
8193 + sid = getsid(pid);
8195 + return posix_error();
8196 + return PyInt_FromLong((long)sid);
8198 +#endif /* HAVE_GETSID */
8202 +PyDoc_STRVAR(posix_setsid__doc__,
8204 +Call the system call setsid().");
8207 +posix_setsid(PyObject *self, PyObject *noargs)
8210 + return posix_error();
8211 + Py_INCREF(Py_None);
8214 +#endif /* HAVE_SETSID */
8216 +#ifdef HAVE_SETPGID
8217 +PyDoc_STRVAR(posix_setpgid__doc__,
8218 +"setpgid(pid, pgrp)\n\n\
8219 +Call the system call setpgid().");
8222 +posix_setpgid(PyObject *self, PyObject *args)
8225 + if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
8227 + if (setpgid(pid, pgrp) < 0)
8228 + return posix_error();
8229 + Py_INCREF(Py_None);
8232 +#endif /* HAVE_SETPGID */
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.");
8241 +posix_tcgetpgrp(PyObject *self, PyObject *args)
8244 + if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
8246 + pgid = tcgetpgrp(fd);
8248 + return posix_error();
8249 + return PyInt_FromLong((long)pgid);
8251 +#endif /* HAVE_TCGETPGRP */
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.");
8260 +posix_tcsetpgrp(PyObject *self, PyObject *args)
8263 + if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
8265 + if (tcsetpgrp(fd, pgid) < 0)
8266 + return posix_error();
8267 + Py_INCREF(Py_None);
8270 +#endif /* HAVE_TCSETPGRP */
8272 +/* Functions acting on file descriptors */
8274 +PyDoc_STRVAR(posix_open__doc__,
8275 +"open(filename, flag [, mode=0777]) -> fd\n\n\
8276 +Open a file (for low level IO).");
8279 +posix_open(PyObject *self, PyObject *args)
8281 + char *file = NULL;
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
8296 + return posix_error();
8297 + return PyInt_FromLong((long)fd);
8299 + /* Drop the argument parsing error as narrow strings
8300 + are also valid. */
8305 + if (!PyArg_ParseTuple(args, "eti|i",
8306 + Py_FileSystemDefaultEncoding, &file,
8310 + Py_BEGIN_ALLOW_THREADS
8311 + fd = open(file, flag, mode);
8312 + Py_END_ALLOW_THREADS
8314 + return posix_error_with_allocated_filename(file);
8316 + return PyInt_FromLong((long)fd);
8320 +PyDoc_STRVAR(posix_close__doc__,
8322 +Close a file descriptor (for low level IO).");
8325 +posix_close(PyObject *self, PyObject *args)
8328 + if (!PyArg_ParseTuple(args, "i:close", &fd))
8330 + Py_BEGIN_ALLOW_THREADS
8332 + Py_END_ALLOW_THREADS
8334 + return posix_error();
8335 + Py_INCREF(Py_None);
8340 +PyDoc_STRVAR(posix_dup__doc__,
8341 +"dup(fd) -> fd2\n\n\
8342 +Return a duplicate of a file descriptor.");
8345 +posix_dup(PyObject *self, PyObject *args)
8348 + if (!PyArg_ParseTuple(args, "i:dup", &fd))
8350 + Py_BEGIN_ALLOW_THREADS
8352 + Py_END_ALLOW_THREADS
8354 + return posix_error();
8355 + return PyInt_FromLong((long)fd);
8359 +PyDoc_STRVAR(posix_dup2__doc__,
8360 +"dup2(old_fd, new_fd)\n\n\
8361 +Duplicate file descriptor.");
8364 +posix_dup2(PyObject *self, PyObject *args)
8367 + if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
8369 + Py_BEGIN_ALLOW_THREADS
8370 + res = dup2(fd, fd2);
8371 + Py_END_ALLOW_THREADS
8373 + return posix_error();
8374 + Py_INCREF(Py_None);
8379 +PyDoc_STRVAR(posix_lseek__doc__,
8380 +"lseek(fd, pos, how) -> newpos\n\n\
8381 +Set the current position of a file descriptor.");
8384 +posix_lseek(PyObject *self, PyObject *args)
8387 +#if defined(MS_WIN64) || defined(MS_WINDOWS)
8388 + PY_LONG_LONG pos, res;
8393 + if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
8396 + /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8398 + case 0: how = SEEK_SET; break;
8399 + case 1: how = SEEK_CUR; break;
8400 + case 2: how = SEEK_END; break;
8402 +#endif /* SEEK_END */
8404 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8405 + pos = PyInt_AsLong(posobj);
8407 + pos = PyLong_Check(posobj) ?
8408 + PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
8410 + if (PyErr_Occurred())
8413 + Py_BEGIN_ALLOW_THREADS
8414 +#if defined(MS_WIN64) || defined(MS_WINDOWS)
8415 + res = _lseeki64(fd, pos, how);
8417 + res = lseek(fd, pos, how);
8419 + Py_END_ALLOW_THREADS
8421 + return posix_error();
8423 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8424 + return PyInt_FromLong(res);
8426 + return PyLong_FromLongLong(res);
8431 +PyDoc_STRVAR(posix_read__doc__,
8432 +"read(fd, buffersize) -> string\n\n\
8433 +Read a file descriptor.");
8436 +posix_read(PyObject *self, PyObject *args)
8440 + if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8444 + return posix_error();
8446 + buffer = PyString_FromStringAndSize((char *)NULL, size);
8447 + if (buffer == NULL)
8449 + Py_BEGIN_ALLOW_THREADS
8450 + n = read(fd, PyString_AsString(buffer), size);
8451 + Py_END_ALLOW_THREADS
8453 + Py_DECREF(buffer);
8454 + return posix_error();
8457 + _PyString_Resize(&buffer, n);
8462 +PyDoc_STRVAR(posix_write__doc__,
8463 +"write(fd, string) -> byteswritten\n\n\
8464 +Write a string to a file descriptor.");
8467 +posix_write(PyObject *self, PyObject *args)
8473 + if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
8475 + Py_BEGIN_ALLOW_THREADS
8476 + size = write(fd, buffer, (size_t)size);
8477 + Py_END_ALLOW_THREADS
8479 + return posix_error();
8480 + return PyInt_FromSsize_t(size);
8484 +PyDoc_STRVAR(posix_fstat__doc__,
8485 +"fstat(fd) -> stat result\n\n\
8486 +Like stat(), but for an open file descriptor.");
8489 +posix_fstat(PyObject *self, PyObject *args)
8494 + if (!PyArg_ParseTuple(args, "i:fstat", &fd))
8497 + /* on OpenVMS we must ensure that all bytes are written to the file */
8500 + Py_BEGIN_ALLOW_THREADS
8501 + res = FSTAT(fd, &st);
8502 + Py_END_ALLOW_THREADS
8505 + return win32_error("fstat", NULL);
8507 + return posix_error();
8511 + return _pystat_fromstructstat(&st);
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.");
8520 +posix_fdopen(PyObject *self, PyObject *args)
8523 + char *orgmode = "r";
8528 + if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
8531 + /* Sanitize mode. See fileobject.c */
8532 + mode = PyMem_MALLOC(strlen(orgmode)+3);
8537 + strcpy(mode, orgmode);
8538 + if (_PyFile_SanitizeMode(mode)) {
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 */
8547 + flags = fcntl(fd, F_GETFL);
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);
8555 + fp = fdopen(fd, mode);
8558 + fp = fdopen(fd, mode);
8560 + Py_END_ALLOW_THREADS
8563 + return posix_error();
8564 + f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
8566 + PyFile_SetBufSize(f, bufsize);
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.");
8576 +posix_isatty(PyObject *self, PyObject *args)
8579 + if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8581 + return PyBool_FromLong(isatty(fd));
8585 +PyDoc_STRVAR(posix_pipe__doc__,
8586 +"pipe() -> (read_end, write_end)\n\n\
8590 +posix_pipe(PyObject *self, PyObject *noargs)
8592 +#if defined(PYOS_OS2)
8593 + HFILE read, write;
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);
8602 + return Py_BuildValue("(ii)", read, write);
8604 +#if !defined(MS_WINDOWS)
8607 + Py_BEGIN_ALLOW_THREADS
8609 + Py_END_ALLOW_THREADS
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;
8617 + Py_BEGIN_ALLOW_THREADS
8618 + ok = CreatePipe(&read, &write, NULL, 0);
8619 + Py_END_ALLOW_THREADS
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 */
8628 +#endif /* HAVE_PIPE */
8632 +PyDoc_STRVAR(posix_mkfifo__doc__,
8633 +"mkfifo(filename [, mode=0666])\n\n\
8634 +Create a FIFO (a POSIX named pipe).");
8637 +posix_mkfifo(PyObject *self, PyObject *args)
8642 + if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
8644 + Py_BEGIN_ALLOW_THREADS
8645 + res = mkfifo(filename, mode);
8646 + Py_END_ALLOW_THREADS
8648 + return posix_error();
8649 + Py_INCREF(Py_None);
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.");
8667 +posix_mknod(PyObject *self, PyObject *args)
8673 + if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
8675 + Py_BEGIN_ALLOW_THREADS
8676 + res = mknod(filename, mode, device);
8677 + Py_END_ALLOW_THREADS
8679 + return posix_error();
8680 + Py_INCREF(Py_None);
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.");
8691 +posix_major(PyObject *self, PyObject *args)
8694 + if (!PyArg_ParseTuple(args, "i:major", &device))
8696 + return PyInt_FromLong((long)major(device));
8699 +PyDoc_STRVAR(posix_minor__doc__,
8700 +"minor(device) -> minor number\n\
8701 +Extracts a device minor number from a raw device number.");
8704 +posix_minor(PyObject *self, PyObject *args)
8707 + if (!PyArg_ParseTuple(args, "i:minor", &device))
8709 + return PyInt_FromLong((long)minor(device));
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.");
8717 +posix_makedev(PyObject *self, PyObject *args)
8720 + if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8722 + return PyInt_FromLong((long)makedev(major, minor));
8724 +#endif /* device macros */
8727 +#ifdef HAVE_FTRUNCATE
8728 +PyDoc_STRVAR(posix_ftruncate__doc__,
8729 +"ftruncate(fd, length)\n\n\
8730 +Truncate a file to a specified length.");
8733 +posix_ftruncate(PyObject *self, PyObject *args)
8740 + if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
8743 +#if !defined(HAVE_LARGEFILE_SUPPORT)
8744 + length = PyInt_AsLong(lenobj);
8746 + length = PyLong_Check(lenobj) ?
8747 + PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
8749 + if (PyErr_Occurred())
8752 + Py_BEGIN_ALLOW_THREADS
8753 + res = ftruncate(fd, length);
8754 + Py_END_ALLOW_THREADS
8756 + PyErr_SetFromErrno(PyExc_IOError);
8759 + Py_INCREF(Py_None);
8765 +PyDoc_STRVAR(posix_putenv__doc__,
8766 +"putenv(key, value)\n\n\
8767 +Change or add an environment variable.");
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;
8774 +posix_putenv(PyObject *self, PyObject *args)
8781 + if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
8784 +#if defined(PYOS_OS2)
8785 + if (stricmp(s1, "BEGINLIBPATH") == 0) {
8788 + rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
8789 + if (rc != NO_ERROR)
8790 + return os2_error(rc);
8792 + } else if (stricmp(s1, "ENDLIBPATH") == 0) {
8795 + rc = DosSetExtLIBPATH(s2, END_LIBPATH);
8796 + if (rc != NO_ERROR)
8797 + return os2_error(rc);
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);
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 */
8825 + Py_DECREF(newstr);
8828 +#if defined(PYOS_OS2)
8831 + Py_INCREF(Py_None);
8834 +#endif /* putenv */
8836 +#ifdef HAVE_UNSETENV
8837 +PyDoc_STRVAR(posix_unsetenv__doc__,
8838 +"unsetenv(key)\n\n\
8839 +Delete an environment variable.");
8842 +posix_unsetenv(PyObject *self, PyObject *args)
8846 + if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
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.
8856 + if (PyDict_DelItem(posix_putenv_garbage,
8857 + PyTuple_GET_ITEM(args, 0))) {
8858 + /* really not much we can do; just leak */
8862 + Py_INCREF(Py_None);
8865 +#endif /* unsetenv */
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.");
8873 +posix_strerror(PyObject *self, PyObject *args)
8877 + if (!PyArg_ParseTuple(args, "i:strerror", &code))
8879 + message = strerror(code);
8880 + if (message == NULL) {
8881 + PyErr_SetString(PyExc_ValueError,
8882 + "strerror() argument out of range");
8885 + return PyString_FromString(message);
8887 +#endif /* strerror */
8890 +#ifdef HAVE_SYS_WAIT_H
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.");
8898 +posix_WCOREDUMP(PyObject *self, PyObject *args)
8901 + WAIT_STATUS_INT(status) = 0;
8903 + if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8906 + return PyBool_FromLong(WCOREDUMP(status));
8908 +#endif /* WCOREDUMP */
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.");
8917 +posix_WIFCONTINUED(PyObject *self, PyObject *args)
8920 + WAIT_STATUS_INT(status) = 0;
8922 + if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8925 + return PyBool_FromLong(WIFCONTINUED(status));
8927 +#endif /* WIFCONTINUED */
8930 +PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
8931 +"WIFSTOPPED(status) -> bool\n\n\
8932 +Return True if the process returning 'status' was stopped.");
8935 +posix_WIFSTOPPED(PyObject *self, PyObject *args)
8938 + WAIT_STATUS_INT(status) = 0;
8940 + if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8943 + return PyBool_FromLong(WIFSTOPPED(status));
8945 +#endif /* WIFSTOPPED */
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.");
8953 +posix_WIFSIGNALED(PyObject *self, PyObject *args)
8956 + WAIT_STATUS_INT(status) = 0;
8958 + if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8961 + return PyBool_FromLong(WIFSIGNALED(status));
8963 +#endif /* WIFSIGNALED */
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\
8972 +posix_WIFEXITED(PyObject *self, PyObject *args)
8975 + WAIT_STATUS_INT(status) = 0;
8977 + if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8980 + return PyBool_FromLong(WIFEXITED(status));
8982 +#endif /* WIFEXITED */
8985 +PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
8986 +"WEXITSTATUS(status) -> integer\n\n\
8987 +Return the process return code from 'status'.");
8990 +posix_WEXITSTATUS(PyObject *self, PyObject *args)
8993 + WAIT_STATUS_INT(status) = 0;
8995 + if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8998 + return Py_BuildValue("i", WEXITSTATUS(status));
9000 +#endif /* WEXITSTATUS */
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\
9009 +posix_WTERMSIG(PyObject *self, PyObject *args)
9012 + WAIT_STATUS_INT(status) = 0;
9014 + if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9017 + return Py_BuildValue("i", WTERMSIG(status));
9019 +#endif /* WTERMSIG */
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.");
9028 +posix_WSTOPSIG(PyObject *self, PyObject *args)
9031 + WAIT_STATUS_INT(status) = 0;
9033 + if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9036 + return Py_BuildValue("i", WSTOPSIG(status));
9038 +#endif /* WSTOPSIG */
9040 +#endif /* HAVE_SYS_WAIT_H */
9043 +#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
9045 +/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9046 + needed definitions in sys/statvfs.h */
9049 +#include <sys/statvfs.h>
9052 +_pystatvfs_fromstructstatvfs(struct statvfs st) {
9053 + PyObject *v = PyStructSequence_New(&StatVFSResultType);
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));
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));
9090 +PyDoc_STRVAR(posix_fstatvfs__doc__,
9091 +"fstatvfs(fd) -> statvfs result\n\n\
9092 +Perform an fstatvfs system call on the given fd.");
9095 +posix_fstatvfs(PyObject *self, PyObject *args)
9098 + struct statvfs st;
9100 + if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9102 + Py_BEGIN_ALLOW_THREADS
9103 + res = fstatvfs(fd, &st);
9104 + Py_END_ALLOW_THREADS
9106 + return posix_error();
9108 + return _pystatvfs_fromstructstatvfs(st);
9110 +#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
9113 +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
9114 +#include <sys/statvfs.h>
9116 +PyDoc_STRVAR(posix_statvfs__doc__,
9117 +"statvfs(path) -> statvfs result\n\n\
9118 +Perform a statvfs system call on the given path.");
9121 +posix_statvfs(PyObject *self, PyObject *args)
9125 + struct statvfs st;
9126 + if (!PyArg_ParseTuple(args, "s:statvfs", &path))
9128 + Py_BEGIN_ALLOW_THREADS
9129 + res = statvfs(path, &st);
9130 + Py_END_ALLOW_THREADS
9132 + return posix_error_with_filename(path);
9134 + return _pystatvfs_fromstructstatvfs(st);
9136 +#endif /* HAVE_STATVFS */
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.");
9147 +posix_tempnam(PyObject *self, PyObject *args)
9149 + PyObject *result = NULL;
9154 + if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
9157 + if (PyErr_Warn(PyExc_RuntimeWarning,
9158 + "tempnam is a potential security risk to your program") < 0)
9162 + name = _tempnam(dir, pfx);
9164 + name = tempnam(dir, pfx);
9167 + return PyErr_NoMemory();
9168 + result = PyString_FromString(name);
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.");
9181 +posix_tmpfile(PyObject *self, PyObject *noargs)
9187 + return posix_error();
9188 + return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
9194 +PyDoc_STRVAR(posix_tmpnam__doc__,
9195 +"tmpnam() -> string\n\n\
9196 +Return a unique name for a temporary file.");
9199 +posix_tmpnam(PyObject *self, PyObject *noargs)
9201 + char buffer[L_tmpnam];
9204 + if (PyErr_Warn(PyExc_RuntimeWarning,
9205 + "tmpnam is a potential security risk to your program") < 0)
9208 +#ifdef USE_TMPNAM_R
9209 + name = tmpnam_r(buffer);
9211 + name = tmpnam(buffer);
9213 + if (name == NULL) {
9214 + PyObject *err = Py_BuildValue("is", 0,
9215 +#ifdef USE_TMPNAM_R
9216 + "unexpected NULL from tmpnam_r"
9218 + "unexpected NULL from tmpnam"
9221 + PyErr_SetObject(PyExc_OSError, err);
9225 + return PyString_FromString(buffer);
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.
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.
9247 +conv_confname(PyObject *arg, int *valuep, struct constdef *table,
9250 + if (PyInt_Check(arg)) {
9251 + *valuep = PyInt_AS_LONG(arg);
9254 + if (PyString_Check(arg)) {
9255 + /* look up the value in the table using a binary search */
9258 + size_t hi = tablesize;
9260 + char *confname = PyString_AS_STRING(arg);
9262 + mid = (lo + hi) / 2;
9263 + cmp = strcmp(confname, table[mid].name);
9269 + *valuep = table[mid].value;
9273 + PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9276 + PyErr_SetString(PyExc_TypeError,
9277 + "configuration names must be strings or integers");
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},
9287 +#ifdef _PC_ABI_ASYNC_IO
9288 + {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
9290 +#ifdef _PC_ASYNC_IO
9291 + {"PC_ASYNC_IO", _PC_ASYNC_IO},
9293 +#ifdef _PC_CHOWN_RESTRICTED
9294 + {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
9296 +#ifdef _PC_FILESIZEBITS
9297 + {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
9300 + {"PC_LAST", _PC_LAST},
9302 +#ifdef _PC_LINK_MAX
9303 + {"PC_LINK_MAX", _PC_LINK_MAX},
9305 +#ifdef _PC_MAX_CANON
9306 + {"PC_MAX_CANON", _PC_MAX_CANON},
9308 +#ifdef _PC_MAX_INPUT
9309 + {"PC_MAX_INPUT", _PC_MAX_INPUT},
9311 +#ifdef _PC_NAME_MAX
9312 + {"PC_NAME_MAX", _PC_NAME_MAX},
9314 +#ifdef _PC_NO_TRUNC
9315 + {"PC_NO_TRUNC", _PC_NO_TRUNC},
9317 +#ifdef _PC_PATH_MAX
9318 + {"PC_PATH_MAX", _PC_PATH_MAX},
9320 +#ifdef _PC_PIPE_BUF
9321 + {"PC_PIPE_BUF", _PC_PIPE_BUF},
9324 + {"PC_PRIO_IO", _PC_PRIO_IO},
9326 +#ifdef _PC_SOCK_MAXBUF
9327 + {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
9330 + {"PC_SYNC_IO", _PC_SYNC_IO},
9332 +#ifdef _PC_VDISABLE
9333 + {"PC_VDISABLE", _PC_VDISABLE},
9338 +conv_path_confname(PyObject *arg, int *valuep)
9340 + return conv_confname(arg, valuep, posix_constants_pathconf,
9341 + sizeof(posix_constants_pathconf)
9342 + / sizeof(struct constdef));
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.");
9353 +posix_fpathconf(PyObject *self, PyObject *args)
9355 + PyObject *result = NULL;
9358 + if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9359 + conv_path_confname, &name)) {
9363 + limit = fpathconf(fd, name);
9364 + if (limit == -1 && errno != 0)
9367 + result = PyInt_FromLong(limit);
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.");
9381 +posix_pathconf(PyObject *self, PyObject *args)
9383 + PyObject *result = NULL;
9387 + if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
9388 + conv_path_confname, &name)) {
9392 + limit = pathconf(path, name);
9393 + if (limit == -1 && errno != 0) {
9394 + if (errno == EINVAL)
9395 + /* could be a path or name problem */
9398 + posix_error_with_filename(path);
9401 + result = PyInt_FromLong(limit);
9407 +#ifdef HAVE_CONFSTR
9408 +static struct constdef posix_constants_confstr[] = {
9409 +#ifdef _CS_ARCHITECTURE
9410 + {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
9412 +#ifdef _CS_HOSTNAME
9413 + {"CS_HOSTNAME", _CS_HOSTNAME},
9415 +#ifdef _CS_HW_PROVIDER
9416 + {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
9418 +#ifdef _CS_HW_SERIAL
9419 + {"CS_HW_SERIAL", _CS_HW_SERIAL},
9421 +#ifdef _CS_INITTAB_NAME
9422 + {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
9424 +#ifdef _CS_LFS64_CFLAGS
9425 + {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
9427 +#ifdef _CS_LFS64_LDFLAGS
9428 + {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
9430 +#ifdef _CS_LFS64_LIBS
9431 + {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
9433 +#ifdef _CS_LFS64_LINTFLAGS
9434 + {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
9436 +#ifdef _CS_LFS_CFLAGS
9437 + {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
9439 +#ifdef _CS_LFS_LDFLAGS
9440 + {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
9442 +#ifdef _CS_LFS_LIBS
9443 + {"CS_LFS_LIBS", _CS_LFS_LIBS},
9445 +#ifdef _CS_LFS_LINTFLAGS
9446 + {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
9449 + {"CS_MACHINE", _CS_MACHINE},
9452 + {"CS_PATH", _CS_PATH},
9455 + {"CS_RELEASE", _CS_RELEASE},
9457 +#ifdef _CS_SRPC_DOMAIN
9458 + {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
9461 + {"CS_SYSNAME", _CS_SYSNAME},
9464 + {"CS_VERSION", _CS_VERSION},
9466 +#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
9467 + {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
9469 +#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
9470 + {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
9472 +#ifdef _CS_XBS5_ILP32_OFF32_LIBS
9473 + {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
9475 +#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
9476 + {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
9478 +#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
9479 + {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
9481 +#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
9482 + {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
9484 +#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
9485 + {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
9487 +#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
9488 + {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
9490 +#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
9491 + {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
9493 +#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
9494 + {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
9496 +#ifdef _CS_XBS5_LP64_OFF64_LIBS
9497 + {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
9499 +#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
9500 + {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
9502 +#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
9503 + {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
9505 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
9506 + {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
9508 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
9509 + {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
9511 +#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
9512 + {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
9514 +#ifdef _MIPS_CS_AVAIL_PROCESSORS
9515 + {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
9517 +#ifdef _MIPS_CS_BASE
9518 + {"MIPS_CS_BASE", _MIPS_CS_BASE},
9520 +#ifdef _MIPS_CS_HOSTID
9521 + {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
9523 +#ifdef _MIPS_CS_HW_NAME
9524 + {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
9526 +#ifdef _MIPS_CS_NUM_PROCESSORS
9527 + {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
9529 +#ifdef _MIPS_CS_OSREL_MAJ
9530 + {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
9532 +#ifdef _MIPS_CS_OSREL_MIN
9533 + {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
9535 +#ifdef _MIPS_CS_OSREL_PATCH
9536 + {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
9538 +#ifdef _MIPS_CS_OS_NAME
9539 + {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
9541 +#ifdef _MIPS_CS_OS_PROVIDER
9542 + {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
9544 +#ifdef _MIPS_CS_PROCESSORS
9545 + {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
9547 +#ifdef _MIPS_CS_SERIAL
9548 + {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
9550 +#ifdef _MIPS_CS_VENDOR
9551 + {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
9556 +conv_confstr_confname(PyObject *arg, int *valuep)
9558 + return conv_confname(arg, valuep, posix_constants_confstr,
9559 + sizeof(posix_constants_confstr)
9560 + / sizeof(struct constdef));
9563 +PyDoc_STRVAR(posix_confstr__doc__,
9564 +"confstr(name) -> string\n\n\
9565 +Return a string-valued system configuration variable.");
9568 +posix_confstr(PyObject *self, PyObject *args)
9570 + PyObject *result = NULL;
9574 + if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
9578 + len = confstr(name, buffer, sizeof(buffer));
9585 + Py_INCREF(Py_None);
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);
9595 + result = PyString_FromStringAndSize(buffer, len-1);
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},
9608 +#ifdef _SC_2_C_BIND
9609 + {"SC_2_C_BIND", _SC_2_C_BIND},
9612 + {"SC_2_C_DEV", _SC_2_C_DEV},
9614 +#ifdef _SC_2_C_VERSION
9615 + {"SC_2_C_VERSION", _SC_2_C_VERSION},
9617 +#ifdef _SC_2_FORT_DEV
9618 + {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
9620 +#ifdef _SC_2_FORT_RUN
9621 + {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
9623 +#ifdef _SC_2_LOCALEDEF
9624 + {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
9626 +#ifdef _SC_2_SW_DEV
9627 + {"SC_2_SW_DEV", _SC_2_SW_DEV},
9630 + {"SC_2_UPE", _SC_2_UPE},
9632 +#ifdef _SC_2_VERSION
9633 + {"SC_2_VERSION", _SC_2_VERSION},
9635 +#ifdef _SC_ABI_ASYNCHRONOUS_IO
9636 + {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
9639 + {"SC_ACL", _SC_ACL},
9641 +#ifdef _SC_AIO_LISTIO_MAX
9642 + {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
9645 + {"SC_AIO_MAX", _SC_AIO_MAX},
9647 +#ifdef _SC_AIO_PRIO_DELTA_MAX
9648 + {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
9651 + {"SC_ARG_MAX", _SC_ARG_MAX},
9653 +#ifdef _SC_ASYNCHRONOUS_IO
9654 + {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
9656 +#ifdef _SC_ATEXIT_MAX
9657 + {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
9660 + {"SC_AUDIT", _SC_AUDIT},
9662 +#ifdef _SC_AVPHYS_PAGES
9663 + {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
9665 +#ifdef _SC_BC_BASE_MAX
9666 + {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
9668 +#ifdef _SC_BC_DIM_MAX
9669 + {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
9671 +#ifdef _SC_BC_SCALE_MAX
9672 + {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
9674 +#ifdef _SC_BC_STRING_MAX
9675 + {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
9678 + {"SC_CAP", _SC_CAP},
9680 +#ifdef _SC_CHARCLASS_NAME_MAX
9681 + {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
9683 +#ifdef _SC_CHAR_BIT
9684 + {"SC_CHAR_BIT", _SC_CHAR_BIT},
9686 +#ifdef _SC_CHAR_MAX
9687 + {"SC_CHAR_MAX", _SC_CHAR_MAX},
9689 +#ifdef _SC_CHAR_MIN
9690 + {"SC_CHAR_MIN", _SC_CHAR_MIN},
9692 +#ifdef _SC_CHILD_MAX
9693 + {"SC_CHILD_MAX", _SC_CHILD_MAX},
9696 + {"SC_CLK_TCK", _SC_CLK_TCK},
9698 +#ifdef _SC_COHER_BLKSZ
9699 + {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
9701 +#ifdef _SC_COLL_WEIGHTS_MAX
9702 + {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
9704 +#ifdef _SC_DCACHE_ASSOC
9705 + {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
9707 +#ifdef _SC_DCACHE_BLKSZ
9708 + {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
9710 +#ifdef _SC_DCACHE_LINESZ
9711 + {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
9713 +#ifdef _SC_DCACHE_SZ
9714 + {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
9716 +#ifdef _SC_DCACHE_TBLKSZ
9717 + {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
9719 +#ifdef _SC_DELAYTIMER_MAX
9720 + {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
9722 +#ifdef _SC_EQUIV_CLASS_MAX
9723 + {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
9725 +#ifdef _SC_EXPR_NEST_MAX
9726 + {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
9729 + {"SC_FSYNC", _SC_FSYNC},
9731 +#ifdef _SC_GETGR_R_SIZE_MAX
9732 + {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
9734 +#ifdef _SC_GETPW_R_SIZE_MAX
9735 + {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
9737 +#ifdef _SC_ICACHE_ASSOC
9738 + {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
9740 +#ifdef _SC_ICACHE_BLKSZ
9741 + {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
9743 +#ifdef _SC_ICACHE_LINESZ
9744 + {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
9746 +#ifdef _SC_ICACHE_SZ
9747 + {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
9750 + {"SC_INF", _SC_INF},
9753 + {"SC_INT_MAX", _SC_INT_MAX},
9756 + {"SC_INT_MIN", _SC_INT_MIN},
9759 + {"SC_IOV_MAX", _SC_IOV_MAX},
9761 +#ifdef _SC_IP_SECOPTS
9762 + {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
9764 +#ifdef _SC_JOB_CONTROL
9765 + {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
9767 +#ifdef _SC_KERN_POINTERS
9768 + {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
9770 +#ifdef _SC_KERN_SIM
9771 + {"SC_KERN_SIM", _SC_KERN_SIM},
9773 +#ifdef _SC_LINE_MAX
9774 + {"SC_LINE_MAX", _SC_LINE_MAX},
9776 +#ifdef _SC_LOGIN_NAME_MAX
9777 + {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
9779 +#ifdef _SC_LOGNAME_MAX
9780 + {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
9782 +#ifdef _SC_LONG_BIT
9783 + {"SC_LONG_BIT", _SC_LONG_BIT},
9786 + {"SC_MAC", _SC_MAC},
9788 +#ifdef _SC_MAPPED_FILES
9789 + {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
9792 + {"SC_MAXPID", _SC_MAXPID},
9794 +#ifdef _SC_MB_LEN_MAX
9795 + {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
9798 + {"SC_MEMLOCK", _SC_MEMLOCK},
9800 +#ifdef _SC_MEMLOCK_RANGE
9801 + {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
9803 +#ifdef _SC_MEMORY_PROTECTION
9804 + {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
9806 +#ifdef _SC_MESSAGE_PASSING
9807 + {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
9809 +#ifdef _SC_MMAP_FIXED_ALIGNMENT
9810 + {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
9812 +#ifdef _SC_MQ_OPEN_MAX
9813 + {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
9815 +#ifdef _SC_MQ_PRIO_MAX
9816 + {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
9818 +#ifdef _SC_NACLS_MAX
9819 + {"SC_NACLS_MAX", _SC_NACLS_MAX},
9821 +#ifdef _SC_NGROUPS_MAX
9822 + {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
9824 +#ifdef _SC_NL_ARGMAX
9825 + {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
9827 +#ifdef _SC_NL_LANGMAX
9828 + {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
9830 +#ifdef _SC_NL_MSGMAX
9831 + {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
9834 + {"SC_NL_NMAX", _SC_NL_NMAX},
9836 +#ifdef _SC_NL_SETMAX
9837 + {"SC_NL_SETMAX", _SC_NL_SETMAX},
9839 +#ifdef _SC_NL_TEXTMAX
9840 + {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
9842 +#ifdef _SC_NPROCESSORS_CONF
9843 + {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
9845 +#ifdef _SC_NPROCESSORS_ONLN
9846 + {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
9848 +#ifdef _SC_NPROC_CONF
9849 + {"SC_NPROC_CONF", _SC_NPROC_CONF},
9851 +#ifdef _SC_NPROC_ONLN
9852 + {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
9855 + {"SC_NZERO", _SC_NZERO},
9857 +#ifdef _SC_OPEN_MAX
9858 + {"SC_OPEN_MAX", _SC_OPEN_MAX},
9860 +#ifdef _SC_PAGESIZE
9861 + {"SC_PAGESIZE", _SC_PAGESIZE},
9863 +#ifdef _SC_PAGE_SIZE
9864 + {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
9866 +#ifdef _SC_PASS_MAX
9867 + {"SC_PASS_MAX", _SC_PASS_MAX},
9869 +#ifdef _SC_PHYS_PAGES
9870 + {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
9873 + {"SC_PII", _SC_PII},
9875 +#ifdef _SC_PII_INTERNET
9876 + {"SC_PII_INTERNET", _SC_PII_INTERNET},
9878 +#ifdef _SC_PII_INTERNET_DGRAM
9879 + {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
9881 +#ifdef _SC_PII_INTERNET_STREAM
9882 + {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
9885 + {"SC_PII_OSI", _SC_PII_OSI},
9887 +#ifdef _SC_PII_OSI_CLTS
9888 + {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
9890 +#ifdef _SC_PII_OSI_COTS
9891 + {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
9893 +#ifdef _SC_PII_OSI_M
9894 + {"SC_PII_OSI_M", _SC_PII_OSI_M},
9896 +#ifdef _SC_PII_SOCKET
9897 + {"SC_PII_SOCKET", _SC_PII_SOCKET},
9900 + {"SC_PII_XTI", _SC_PII_XTI},
9903 + {"SC_POLL", _SC_POLL},
9905 +#ifdef _SC_PRIORITIZED_IO
9906 + {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
9908 +#ifdef _SC_PRIORITY_SCHEDULING
9909 + {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
9911 +#ifdef _SC_REALTIME_SIGNALS
9912 + {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
9914 +#ifdef _SC_RE_DUP_MAX
9915 + {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
9917 +#ifdef _SC_RTSIG_MAX
9918 + {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
9920 +#ifdef _SC_SAVED_IDS
9921 + {"SC_SAVED_IDS", _SC_SAVED_IDS},
9923 +#ifdef _SC_SCHAR_MAX
9924 + {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
9926 +#ifdef _SC_SCHAR_MIN
9927 + {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
9930 + {"SC_SELECT", _SC_SELECT},
9932 +#ifdef _SC_SEMAPHORES
9933 + {"SC_SEMAPHORES", _SC_SEMAPHORES},
9935 +#ifdef _SC_SEM_NSEMS_MAX
9936 + {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
9938 +#ifdef _SC_SEM_VALUE_MAX
9939 + {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
9941 +#ifdef _SC_SHARED_MEMORY_OBJECTS
9942 + {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
9944 +#ifdef _SC_SHRT_MAX
9945 + {"SC_SHRT_MAX", _SC_SHRT_MAX},
9947 +#ifdef _SC_SHRT_MIN
9948 + {"SC_SHRT_MIN", _SC_SHRT_MIN},
9950 +#ifdef _SC_SIGQUEUE_MAX
9951 + {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
9953 +#ifdef _SC_SIGRT_MAX
9954 + {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
9956 +#ifdef _SC_SIGRT_MIN
9957 + {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
9959 +#ifdef _SC_SOFTPOWER
9960 + {"SC_SOFTPOWER", _SC_SOFTPOWER},
9962 +#ifdef _SC_SPLIT_CACHE
9963 + {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
9965 +#ifdef _SC_SSIZE_MAX
9966 + {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
9968 +#ifdef _SC_STACK_PROT
9969 + {"SC_STACK_PROT", _SC_STACK_PROT},
9971 +#ifdef _SC_STREAM_MAX
9972 + {"SC_STREAM_MAX", _SC_STREAM_MAX},
9974 +#ifdef _SC_SYNCHRONIZED_IO
9975 + {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
9978 + {"SC_THREADS", _SC_THREADS},
9980 +#ifdef _SC_THREAD_ATTR_STACKADDR
9981 + {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
9983 +#ifdef _SC_THREAD_ATTR_STACKSIZE
9984 + {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
9986 +#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
9987 + {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
9989 +#ifdef _SC_THREAD_KEYS_MAX
9990 + {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
9992 +#ifdef _SC_THREAD_PRIORITY_SCHEDULING
9993 + {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
9995 +#ifdef _SC_THREAD_PRIO_INHERIT
9996 + {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
9998 +#ifdef _SC_THREAD_PRIO_PROTECT
9999 + {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
10001 +#ifdef _SC_THREAD_PROCESS_SHARED
10002 + {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
10004 +#ifdef _SC_THREAD_SAFE_FUNCTIONS
10005 + {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
10007 +#ifdef _SC_THREAD_STACK_MIN
10008 + {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
10010 +#ifdef _SC_THREAD_THREADS_MAX
10011 + {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
10014 + {"SC_TIMERS", _SC_TIMERS},
10016 +#ifdef _SC_TIMER_MAX
10017 + {"SC_TIMER_MAX", _SC_TIMER_MAX},
10019 +#ifdef _SC_TTY_NAME_MAX
10020 + {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
10022 +#ifdef _SC_TZNAME_MAX
10023 + {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
10025 +#ifdef _SC_T_IOV_MAX
10026 + {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
10028 +#ifdef _SC_UCHAR_MAX
10029 + {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
10031 +#ifdef _SC_UINT_MAX
10032 + {"SC_UINT_MAX", _SC_UINT_MAX},
10034 +#ifdef _SC_UIO_MAXIOV
10035 + {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
10037 +#ifdef _SC_ULONG_MAX
10038 + {"SC_ULONG_MAX", _SC_ULONG_MAX},
10040 +#ifdef _SC_USHRT_MAX
10041 + {"SC_USHRT_MAX", _SC_USHRT_MAX},
10043 +#ifdef _SC_VERSION
10044 + {"SC_VERSION", _SC_VERSION},
10046 +#ifdef _SC_WORD_BIT
10047 + {"SC_WORD_BIT", _SC_WORD_BIT},
10049 +#ifdef _SC_XBS5_ILP32_OFF32
10050 + {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
10052 +#ifdef _SC_XBS5_ILP32_OFFBIG
10053 + {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
10055 +#ifdef _SC_XBS5_LP64_OFF64
10056 + {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
10058 +#ifdef _SC_XBS5_LPBIG_OFFBIG
10059 + {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
10061 +#ifdef _SC_XOPEN_CRYPT
10062 + {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
10064 +#ifdef _SC_XOPEN_ENH_I18N
10065 + {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
10067 +#ifdef _SC_XOPEN_LEGACY
10068 + {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
10070 +#ifdef _SC_XOPEN_REALTIME
10071 + {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
10073 +#ifdef _SC_XOPEN_REALTIME_THREADS
10074 + {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
10076 +#ifdef _SC_XOPEN_SHM
10077 + {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
10079 +#ifdef _SC_XOPEN_UNIX
10080 + {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
10082 +#ifdef _SC_XOPEN_VERSION
10083 + {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
10085 +#ifdef _SC_XOPEN_XCU_VERSION
10086 + {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
10088 +#ifdef _SC_XOPEN_XPG2
10089 + {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
10091 +#ifdef _SC_XOPEN_XPG3
10092 + {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
10094 +#ifdef _SC_XOPEN_XPG4
10095 + {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
10100 +conv_sysconf_confname(PyObject *arg, int *valuep)
10102 + return conv_confname(arg, valuep, posix_constants_sysconf,
10103 + sizeof(posix_constants_sysconf)
10104 + / sizeof(struct constdef));
10107 +PyDoc_STRVAR(posix_sysconf__doc__,
10108 +"sysconf(name) -> integer\n\n\
10109 +Return an integer-valued system configuration variable.");
10112 +posix_sysconf(PyObject *self, PyObject *args)
10114 + PyObject *result = NULL;
10117 + if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10121 + value = sysconf(name);
10122 + if (value == -1 && errno != 0)
10125 + result = PyInt_FromLong(value);
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.
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.
10143 +cmp_constdefs(const void *v1, const void *v2)
10145 + const struct constdef *c1 =
10146 + (const struct constdef *) v1;
10147 + const struct constdef *c2 =
10148 + (const struct constdef *) v2;
10150 + return strcmp(c1->name, c2->name);
10154 +setup_confname_table(struct constdef *table, size_t tablesize,
10155 + char *tablename, PyObject *module)
10157 + PyObject *d = NULL;
10160 + qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10161 + d = PyDict_New();
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) {
10174 + return PyModule_AddObject(module, tablename, d);
10177 +/* Return -1 on failure, 0 on success. */
10179 +setup_confname_tables(PyObject *module)
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))
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))
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))
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.");
10212 +posix_abort(PyObject *self, PyObject *noargs)
10216 + Py_FatalError("abort() called from Python code didn't abort!");
10221 +PyDoc_STRVAR(win32_startfile__doc__,
10222 +"startfile(filepath [, operation]) - Start a file with its associated\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\
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\
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.");
10241 +win32_startfile(PyObject *self, PyObject *args)
10244 + char *operation = NULL;
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)) {
10257 + woperation = PyUnicode_DecodeASCII(operation,
10258 + strlen(operation), NULL);
10259 + if (!woperation) {
10261 + operation = NULL;
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
10272 + Py_XDECREF(woperation);
10273 + if (rc <= (HINSTANCE)32) {
10274 + PyObject *errval = win32_error_unicode("startfile",
10275 + PyUnicode_AS_UNICODE(unipath));
10278 + Py_INCREF(Py_None);
10284 + if (!PyArg_ParseTuple(args, "et|s:startfile",
10285 + Py_FileSystemDefaultEncoding, &filepath,
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);
10297 + PyMem_Free(filepath);
10298 + Py_INCREF(Py_None);
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");
10311 +posix_getloadavg(PyObject *self, PyObject *noargs)
10313 + double loadavg[3];
10314 + if (getloadavg(loadavg, 3)!=3) {
10315 + PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10318 + return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
10324 +PyDoc_STRVAR(win32_urandom__doc__,
10325 +"urandom(n) -> str\n\n\
10326 +Return a string of n random bytes suitable for cryptographic use.");
10328 +typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
10329 + LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
10331 +typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
10332 + BYTE *pbBuffer );
10334 +static CRYPTGENRANDOM pCryptGenRandom = NULL;
10335 +static HCRYPTPROV hCryptProv = 0;
10338 +win32_urandom(PyObject *self, PyObject *args)
10341 + PyObject* result;
10343 + /* Read arguments */
10344 + if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10347 + return PyErr_Format(PyExc_ValueError,
10348 + "negative argument not allowed");
10350 + if (hCryptProv == 0) {
10351 + HINSTANCE hAdvAPI32 = NULL;
10352 + CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
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);
10360 + /* Obtain pointers to the CryptoAPI functions
10361 + This will fail on some early versions of Win95 */
10362 + pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
10364 + "CryptAcquireContextA");
10365 + if (pCryptAcquireContext == NULL)
10366 + return PyErr_Format(PyExc_NotImplementedError,
10367 + "CryptAcquireContextA not found");
10369 + pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
10370 + hAdvAPI32, "CryptGenRandom");
10371 + if (pCryptGenRandom == NULL)
10372 + return PyErr_Format(PyExc_NotImplementedError,
10373 + "CryptGenRandom not found");
10375 + /* Acquire context */
10376 + if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
10377 + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
10378 + return win32_error("CryptAcquireContext", NULL);
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);
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.");
10403 +vms_urandom(PyObject *self, PyObject *args)
10406 + PyObject* result;
10408 + /* Read arguments */
10409 + if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10412 + return PyErr_Format(PyExc_ValueError,
10413 + "negative argument not allowed");
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),
10422 + Py_DECREF(result);
10423 + return PyErr_Format(PyExc_ValueError,
10424 + "RAND_pseudo_bytes");
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__},
10436 + {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
10437 + {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
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__},
10447 +#ifdef HAVE_CTERMID
10448 + {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
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__},
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__},
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__},
10478 + {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
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__},
10486 + {"times", posix_times, METH_NOARGS, posix_times__doc__},
10487 +#endif /* HAVE_TIMES */
10488 + {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
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 */
10502 + {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
10503 +#endif /* HAVE_FORK1 */
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__},
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__},
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 */
10545 + {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
10546 +#endif /* HAVE_PLOCK */
10548 + {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
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__},
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},
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 */
10590 + {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
10591 +#endif /* HAVE_WAIT */
10593 + {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
10594 +#endif /* HAVE_WAIT3 */
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__},
10627 + {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
10629 +#ifdef HAVE_MKFIFO
10630 + {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
10632 +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10633 + {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
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__},
10640 +#ifdef HAVE_FTRUNCATE
10641 + {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
10643 +#ifdef HAVE_PUTENV
10644 + {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
10646 +#ifdef HAVE_UNSETENV
10647 + {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
10649 +#ifdef HAVE_STRERROR
10650 + {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
10652 +#ifdef HAVE_FCHDIR
10653 + {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
10656 + {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
10658 +#ifdef HAVE_FDATASYNC
10659 + {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
10661 +#ifdef HAVE_SYS_WAIT_H
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 */
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 */
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 */
10681 + {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
10682 +#endif /* WTERMSIG */
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__},
10690 +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
10691 + {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
10693 +#ifdef HAVE_TMPFILE
10694 + {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
10696 +#ifdef HAVE_TEMPNAM
10697 + {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
10699 +#ifdef HAVE_TMPNAM
10700 + {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
10702 +#ifdef HAVE_CONFSTR
10703 + {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
10705 +#ifdef HAVE_SYSCONF
10706 + {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
10708 +#ifdef HAVE_FPATHCONF
10709 + {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
10711 +#ifdef HAVE_PATHCONF
10712 + {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
10714 + {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
10716 + {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
10718 +#ifdef HAVE_GETLOADAVG
10719 + {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
10721 + #ifdef MS_WINDOWS
10722 + {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
10725 + {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
10727 + {NULL, NULL} /* Sentinel */
10732 +ins(PyObject *module, char *symbol, long value)
10734 + return PyModule_AddIntConstant(module, symbol, value);
10737 +#if defined(PYOS_OS2)
10738 +/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
10739 +static int insertvalues(PyObject *module)
10742 + ULONG values[QSV_MAX+1];
10744 + char *ver, tmp[50];
10746 + Py_BEGIN_ALLOW_THREADS
10747 + rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
10748 + Py_END_ALLOW_THREADS
10750 + if (rc != NO_ERROR) {
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;
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;
10771 + PyOS_snprintf(tmp, sizeof(tmp),
10772 + "%d-%d", values[QSV_VERSION_MAJOR],
10773 + values[QSV_VERSION_MINOR]);
10777 + /* Add Indicator of the Version of the Operating System */
10778 + if (PyModule_AddStringConstant(module, "version", tmp) < 0)
10781 + /* Add Indicator of Which Drive was Used to Boot the System */
10782 + tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
10786 + return PyModule_AddStringConstant(module, "bootdrive", tmp);
10791 +all_ins(PyObject *d)
10794 + if (ins(d, "F_OK", (long)F_OK)) return -1;
10797 + if (ins(d, "R_OK", (long)R_OK)) return -1;
10800 + if (ins(d, "W_OK", (long)W_OK)) return -1;
10803 + if (ins(d, "X_OK", (long)X_OK)) return -1;
10805 +#ifdef NGROUPS_MAX
10806 + if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
10809 + if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
10812 + if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
10815 + if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
10818 + if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
10821 + if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
10824 + if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
10827 + if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
10830 + if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
10833 + if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
10836 + if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
10839 + if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
10842 + if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
10845 + if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
10848 + if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
10851 + if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
10854 + if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
10857 + if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
10860 + if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
10863 + if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
10865 +#ifdef O_LARGEFILE
10866 + if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
10869 + if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
10872 + if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
10876 +#ifdef O_NOINHERIT
10877 + /* Don't inherit in child processes. */
10878 + if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
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;
10885 +#ifdef O_TEMPORARY
10886 + /* Automatically delete when last handle is closed. */
10887 + if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
10890 + /* Optimize for random access. */
10891 + if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
10893 +#ifdef O_SEQUENTIAL
10894 + /* Optimize for sequential access. */
10895 + if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
10898 +/* GNU extensions. */
10900 + /* Direct disk access. */
10901 + if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
10903 +#ifdef O_DIRECTORY
10904 + /* Must be a directory. */
10905 + if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
10908 + /* Do not follow links. */
10909 + if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
10912 + /* These come from sysexits.h */
10914 + if (ins(d, "EX_OK", (long)EX_OK)) return -1;
10915 +#endif /* EX_OK */
10917 + if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
10918 +#endif /* EX_USAGE */
10920 + if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
10921 +#endif /* EX_DATAERR */
10923 + if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
10924 +#endif /* EX_NOINPUT */
10926 + if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
10927 +#endif /* EX_NOUSER */
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 */
10938 + if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
10939 +#endif /* EX_OSERR */
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 */
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 */
10956 + if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
10957 +#endif /* EX_NOPERM */
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 */
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;
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;
10996 +#if defined(PYOS_OS2)
10997 + if (insertvalues(d)) return -1;
11003 +#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
11004 +#define INITFUNC initnt
11005 +#define MODNAME "nt"
11007 +#elif defined(PYOS_OS2)
11008 +#define INITFUNC initos2
11009 +#define MODNAME "os2"
11012 +#define INITFUNC initposix
11013 +#define MODNAME "posix"
11021 + m = Py_InitModule3(MODNAME,
11027 + /* Initialize environ dictionary */
11028 + v = convertenviron();
11030 + if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11037 + if (setup_confname_tables(m))
11040 + Py_INCREF(PyExc_OSError);
11041 + PyModule_AddObject(m, "error", PyExc_OSError);
11043 +#ifdef HAVE_PUTENV
11044 + if (posix_putenv_garbage == NULL)
11045 + posix_putenv_garbage = PyDict_New();
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;
11057 + statvfs_result_desc.name = MODNAME ".statvfs_result";
11058 + PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
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);
11069 + * Step 2 of weak-linking support on Mac OS X.
11071 + * The code below removes functions that are not available on the
11072 + * currently active platform.
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
11078 +#ifdef HAVE_FSTATVFS
11079 + if (fstatvfs == NULL) {
11080 + if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11084 +#endif /* HAVE_FSTATVFS */
11086 +#ifdef HAVE_STATVFS
11087 + if (statvfs == NULL) {
11088 + if (PyObject_DelAttrString(m, "statvfs") == -1) {
11092 +#endif /* HAVE_STATVFS */
11094 +# ifdef HAVE_LCHOWN
11095 + if (lchown == NULL) {
11096 + if (PyObject_DelAttrString(m, "lchown") == -1) {
11100 +#endif /* HAVE_LCHOWN */
11103 +#endif /* __APPLE__ */
11107 +#ifdef __cplusplus