--- a/components/python/cffi/Makefile Thu Oct 01 15:00:59 2015 -0700
+++ b/components/python/cffi/Makefile Tue Sep 29 14:11:08 2015 -0700
@@ -79,4 +79,5 @@
REQUIRED_PACKAGES += library/python/pycparser-26
REQUIRED_PACKAGES += library/python/pycparser-27
REQUIRED_PACKAGES += library/python/pycparser-34
+REQUIRED_PACKAGES += library/python/pycparser-35
REQUIRED_PACKAGES += system/library
--- a/components/python/pip/Makefile Thu Oct 01 15:00:59 2015 -0700
+++ b/components/python/pip/Makefile Tue Sep 29 14:11:08 2015 -0700
@@ -59,6 +59,8 @@
REQUIRED_PACKAGES += library/python/requests-26
REQUIRED_PACKAGES += library/python/requests-27
REQUIRED_PACKAGES += library/python/requests-34
+REQUIRED_PACKAGES += library/python/requests-35
REQUIRED_PACKAGES += library/python/setuptools-26
REQUIRED_PACKAGES += library/python/setuptools-27
REQUIRED_PACKAGES += library/python/setuptools-34
+REQUIRED_PACKAGES += library/python/setuptools-35
--- a/components/python/python34/python-34.p5m Thu Oct 01 15:00:59 2015 -0700
+++ b/components/python/python34/python-34.p5m Tue Sep 29 14:11:08 2015 -0700
@@ -20,17 +20,6 @@
#
# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
#
-
-# bootstrap: pkgdepend doesn't like python 3.4 yet;
-# remove this block once it is installed on build machine
-# also look for other "XXX bootstrap" comments
-<transform file path=.+\.py$ -> \
- default pkg.depend.bypass-generate .* >
-<transform file path=.+\.pyc$ -> \
- default pkg.depend.bypass-generate .* >
-<transform file path=usr/bin.*$ -> \
- default pkg.depend.bypass-generate .* >
-
<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
<transform file path=.*/(idle_)?tests?/.* -> default facet.optional.test true>
set name=pkg.fmri \
@@ -1001,17 +990,14 @@
file path=usr/lib/python3.4/plat-sunos5/STROPTS.py
file path=usr/lib/python3.4/plat-sunos5/TYPES.py
file path=usr/lib/python3.4/plat-sunos5/regen
-# XXX bootstrap
-#file path=usr/lib/python3.4/platform.py
-# pkg.depend.bypass-generate=.*/MacOS.*
-# pkg.depend.bypass-generate=.*/_gestalt.*
-# pkg.depend.bypass-generate=.*/java/__init__.py
-# pkg.depend.bypass-generate=.*/lang.*
-# pkg.depend.bypass-generate=.*/vms_lib.*
-# pkg.depend.bypass-generate=.*/win32api.*
-# pkg.depend.bypass-generate=.*/win32con.*
-# pkg.depend.bypass-generate=.*/winreg.*
-file path=usr/lib/python3.4/platform.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.4/platform.py pkg.depend.bypass-generate=.*/MacOS.* \
+ pkg.depend.bypass-generate=.*/_gestalt.* \
+ pkg.depend.bypass-generate=.*/java/__init__.py \
+ pkg.depend.bypass-generate=.*/lang.* \
+ pkg.depend.bypass-generate=.*/vms_lib.* \
+ pkg.depend.bypass-generate=.*/win32api.* \
+ pkg.depend.bypass-generate=.*/win32con.* \
+ pkg.depend.bypass-generate=.*/winreg.*
file path=usr/lib/python3.4/plistlib.py
file path=usr/lib/python3.4/poplib.py
file path=usr/lib/python3.4/posixpath.py
@@ -1368,10 +1354,8 @@
file path=usr/lib/python3.4/test/randv2_64.pck
file path=usr/lib/python3.4/test/randv3.pck
file path=usr/lib/python3.4/test/re_tests.py
-# XXX bootstrap
-# file path=usr/lib/python3.4/test/regrtest.py
-# pkg.depend.bypass-generate=.*/msvcrt.*
-file path=usr/lib/python3.4/test/regrtest.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.4/test/regrtest.py \
+ pkg.depend.bypass-generate=.*/msvcrt.*
file path=usr/lib/python3.4/test/relimport.py
file path=usr/lib/python3.4/test/reperf.py
file path=usr/lib/python3.4/test/revocation.crl
--- a/components/python/python34/tkinter-34.p5m Thu Oct 01 15:00:59 2015 -0700
+++ b/components/python/python34/tkinter-34.p5m Tue Sep 29 14:11:08 2015 -0700
@@ -18,17 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
-#
-
-# bootstrap: pkgdepend doesn't like python 3.4 yet;
-# remove this block once it is installed on build machine
-<transform file path=.+\.py$ -> \
- default pkg.depend.bypass-generate .* >
-<transform file path=.+\.pyc$ -> \
- default pkg.depend.bypass-generate .* >
-<transform file path=usr/bin.*$ -> \
- default pkg.depend.bypass-generate .* >
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
#
set name=pkg.fmri \
value=pkg:/library/python/[email protected]$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/Makefile Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,216 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../../../make-rules/shared-macros.mk
+
+COMPONENT_NAME= Python
+COMPONENT_VERSION= 3.5.0
+COMPONENT_PROJECT_URL= http://python.org/
+COMPONENT_SRC= $(COMPONENT_NAME)-$(COMPONENT_VERSION)
+COMPONENT_ARCHIVE= $(COMPONENT_SRC).tar.xz
+COMPONENT_ARCHIVE_HASH= \
+ sha256:d6d7aa1634a5eeeca6ed4fca266982a04f84bd8f3945a9179e20b24ad2e2be91
+COMPONENT_ARCHIVE_URL= $(COMPONENT_PROJECT_URL)ftp/python/3.5.0/$(COMPONENT_ARCHIVE)
+COMPONENT_SIG_URL= $(COMPONENT_ARCHIVE_URL).asc
+COMPONENT_BUGDB= utility/python
+
+TPNO= 24524
+
+include $(WS_MAKE_RULES)/prep.mk
+include $(WS_MAKE_RULES)/configure.mk
+include $(WS_MAKE_RULES)/ips.mk
+include $(WS_MAKE_RULES)/lint-libraries.mk
+
+# Need to preserve timestamp for Grammar files. If the pickle files are older,
+# Python will try to rebuild them.
+PKGSEND_PUBLISH_OPTIONS += -T \*Grammar\*.txt
+PKGSEND_PUBLISH_OPTIONS += -T \*Grammar\*.pickle
+
+# We patch auto* files, so regenerate headers and configure
+COMPONENT_PREP_ACTION = \
+ (cd $(@D) ; autoheader ; autoconf)
+
+# The DTrace patch needs this file to be mode 0755.
+COMPONENT_PRE_BUILD_ACTION=($(CHMOD) +x \
+ $(SOURCE_DIR)/Include/pydtrace_offsets.sh)
+
+# we don't want to leak $(CC_BITS) into BASECFLAGS as it causes problems with
+# python-config
+CC += $(CFLAGS)
+
+C99MODE=
+CPPFLAGS += -IPython
+
+# to find the ncurses headers
+CPPFLAGS += -I/usr/include/ncurses
+# enable large files how they did in JDS
+CPPFLAGS += -D_LARGEFILE64_SOURCE
+
+# libffi for _ctypes
+CPPFLAGS += $(shell pkg-config --cflags-only-I libffi)
+
+# because python links with $(CC) ... $(LDFLAGS) ...
+LDFLAGS = $(CC_BITS) $(CC_PIC)
+
+# build pic
+CFLAGS += $(CC_PIC)
+
+# for DWARF
+CFLAGS.i386 = -preserve_argvalues=complete
+CFLAGS += $(CFLAGS.$(MACH))
+
+# 16-byte memory alignment + interpretation of non-alignment prevents SIGBUS.
+studio_ALIGN.sparc.64 = -xmemalign=16i
+
+# The python build is profile-guided for studio; to see the benefits of that,
+# Python must be compiled with -xO5 and a different build target must be used.
+# Use of xprofile requires that the same options be used during compilation and
+# linking. The targets chosen are based on Solaris 11 minimum supported system
+# requirements.
+COMPONENT_BUILD_TARGETS = profile-opt
+XPROFILE_DIR = $(BUILD_DIR_$(BITS))/.profile
+PYFLAGS.i386 = -xtarget=opteron -xarch=sse2 -xcache=generic
+PYFLAGS.sparc =
+CFLAGS += -xO5 $(PYFLAGS.$(MACH))
+LDFLAGS += -xO5 $(PYFLAGS.$(MACH))
+
+# Python puts its header files in a special place.
+LINT_FLAGS += -I$(SOURCE_DIR)/Include
+
+# PYTHONPATH in the environment can be harmful, but setting it to empty via
+# _INSTALL_ENV causes problems too, so just ignore the entire environment.
+# Because of this, we need to specify PATH in multiple places below.
+ENV += -i
+
+CONFIGURE_ENV += PATH="$(PATH)"
+
+CONFIGURE_OPTIONS += --infodir=$(CONFIGURE_INFODIR)
+CONFIGURE_OPTIONS += --enable-shared
+CONFIGURE_OPTIONS += --with-dtrace
+CONFIGURE_OPTIONS += --with-system-expat
+CONFIGURE_OPTIONS += --with-system-ffi
+CONFIGURE_OPTIONS += --without-gcc
+CONFIGURE_OPTIONS += --without-ensurepip
+CONFIGURE_OPTIONS += --enable-ipv6
+CONFIGURE_OPTIONS += --bindir=/usr/bin
+CONFIGURE_OPTIONS += "ac_cv_func_getentropy=no"
+CONFIGURE_OPTIONS += CPPFLAGS="$(CPPFLAGS)"
+CONFIGURE_OPTIONS += LDFLAGS="$(LDFLAGS)"
+CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS)"
+CONFIGURE_OPTIONS += DFLAGS="-$(BITS)"
+CONFIGURE_OPTIONS += XPROFILE_DIR="$(XPROFILE_DIR)"
+
+COMPONENT_BUILD_ENV += DFLAGS="-$(BITS)"
+COMPONENT_BUILD_ENV += XPROFILE_DIR="$(XPROFILE_DIR)"
+COMPONENT_BUILD_ENV += PATH="$(PATH)"
+
+# Some tests have non-ASCII characters encoded for international domain names;
+# the publish step will fail in 'pkgdepend generate' without this:
+COMPONENT_PUBLISH_ENV += LC_ALL=en_US.UTF-8
+
+# 64 bit shared objects need to go in a 64-bit directory
+COMPONENT_INSTALL_ARGS.64 += DESTSHARED=$(CONFIGURE_PREFIX)/lib/python3.5/lib-dynload
+
+ASLR_MODE = $(ASLR_ENABLE)
+
+# Simplify the definitions of CC, CXX, CFLAGS and LDFLAGS so they hard-code
+# neither paths from our build systems nor Studio-specific options.
+COMPONENT_PRE_INSTALL_ACTION= \
+ (cd $(@D) ; \
+ $(GSED) -i -e 's/^CC=.*/CC=\t\tcc/' -e 's/^CXX=.*/CXX=\t\tCC/' \
+ -e 's/^CFLAGS=.*/CFLAGS=\t\t\$$\(BASECFLAGS) \$$\(OPT) \$$\(EXTRA_CFLAGS)/' \
+ -e 's|^LDFLAGS=.*|LDFLAGS=|' Makefile)
+
+# Because we stripped the Makefile above, we need to pass several things in the
+# environment, and use -e to tell gmake to pay attention to the environment.
+COMPONENT_INSTALL_ENV += CC="$(CC)"
+COMPONENT_INSTALL_ENV += CXX="$(CXX)"
+COMPONENT_INSTALL_ENV += CFLAGS="$(CFLAGS)"
+COMPONENT_INSTALL_ENV += LDFLAGS="$(LDFLAGS)"
+COMPONENT_INSTALL_ENV += PATH="$(PATH)"
+COMPONENT_INSTALL_ARGS += -e
+
+# Strip build machine paths from _sysconfigdata.py & config/Makefile,
+# then (re)compile _sysconfigdata.py since we just updated it.
+# Note that once Python 3.5 has been integrated and propagated to build
+# machines, then the LD_LIBRARY_PATH setting and PROTO_DIR prefix below
+# can both be removed.
+COMPONENT_POST_INSTALL_ACTION= \
+ (cd $(PROTOUSRLIBDIR)/python3.5 ; \
+ $(GSED) -i -e 's|$(SOURCE_DIR)|.|g' -e 's|$(COMPONENT_DIR)|..|g' \
+ -e 's|$(SPRO_VROOT)/bin/||g' _sysconfigdata.py config-3.5m/Makefile; \
+ LD_LIBRARY_PATH=$(PROTOUSRLIBDIR64) $(PROTO_DIR)$(PYTHON.3.5) -m py_compile _sysconfigdata.py)
+
+# common targets
+configure: $(CONFIGURE_64)
+build: $(BUILD_64)
+install: $(INSTALL_64)
+
+# Using "-uall,-network" ensures all tests are run except the network tests.
+# The network tests contain many expected failures when run behind a firewall.
+# The "-v" ensures verbose mode. You can set TESTOPTS_PYTHON_TEST to a
+# particular test if you want to run just one test. For example,
+# $ TESTOPTS_PYTHON_TEST=test_sys gmake -k test
+# Note that when a test succeeds, the builds/*/.tested file gets created. You
+# may need to remove these files, or run "gmake clobber" or "gmake clean"
+# between tests.
+#
+COMPONENT_TEST_ENV = EXTRATESTOPTS="-v -uall,-network $(TESTOPTS_PYTHON_TEST)"
+# The distutils tests need $CC in $PATH.
+COMPONENT_TEST_ENV += PATH="$(SPRO_VROOT)/bin:$(PATH)"
+# Prevent the tests from getting stuck waiting for input.
+COMPONENT_TEST_TARGETS = test < /dev/null
+# Some different values for system testing.
+COMPONENT_SYSTEM_TEST_ENV = EXTRATESTOPTS="-v -uall,-network $(TESTOPTS_PYTHON_TEST)"
+COMPONENT_SYSTEM_TEST_TARGETS =
+COMPONENT_SYSTEM_TEST_CMD= $(PYTHON.3.5)
+COMPONENT_SYSTEM_TEST_ARGS= /usr/lib/python3.5/test/regrtest.py -v -uall,-network
+
+# The test output contains details from each test, in whatever order they
+# complete. The default _TRANSFORMER is not powerful enough to deal with
+# this; we need heavier artillery. Extract just the sections that start
+# with "tests OK." and end with "Re-running failed tests..." for comparison.
+COMPONENT_TEST_TRANSFORMER = $(NAWK)
+COMPONENT_TEST_TRANSFORMS = "'/tests OK./ {results = 1}; /Re-running failed tests in verbose mode/ {results = 0} {if (results) print $0 } '"
+
+test: $(TEST_64)
+system-test: $(SYSTEM_TEST_64)
+
+REQUIRED_PACKAGES += compress/bzip2
+REQUIRED_PACKAGES += compress/xz
+REQUIRED_PACKAGES += database/sqlite-3
+REQUIRED_PACKAGES += library/database/gdbm
+REQUIRED_PACKAGES += library/expat
+REQUIRED_PACKAGES += library/libffi
+REQUIRED_PACKAGES += library/ncurses
+REQUIRED_PACKAGES += library/readline
+REQUIRED_PACKAGES += library/security/openssl
+REQUIRED_PACKAGES += library/zlib
+REQUIRED_PACKAGES += runtime/tcl-8
+REQUIRED_PACKAGES += runtime/tk-8
+REQUIRED_PACKAGES += system/library
+REQUIRED_PACKAGES += system/library/math
+REQUIRED_PACKAGES += system/linker
+REQUIRED_PACKAGES += x11/library/libx11
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/00-dtrace.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,2036 @@
+This patch comes from upstream:
+http://www.jcea.es/artic/python_dtrace-3_4_0_0de6441eedb7.txt
+http://www.jcea.es/artic/python_dtrace.htm
+Follow http://bugs.python.org/issue13405 for plans to get it
+integrated into the main tree.
+
+--- Python-3.4.0/Doc/library/debug.rst
++++ Python-3.4.0/Doc/library/debug.rst
[email protected]@ -15,4 +15,5 @@
+ profile.rst
+ timeit.rst
+ trace.rst
++ dtrace.rst
+ tracemalloc.rst
+--- /dev/null
++++ Python-3.4.0/Doc/library/dtrace.rst
[email protected]@ -0,0 +1,183 @@
++:mod:`dtrace` --- DTrace probes for Python
++===============================================
++
++.. module:: dtrace
++ :synopsis: DTrace probes for Python.
++
++**Source code:** :source:`Lib/dtrace.py`
++
++--------------
++
++The :mod:`dtrace` module indicates if the CPython executable currently
++running has been compiled with DTrace probes support.
++
++.. impl-detail::
++
++ DTrace probes are implementation details of the CPython interpreter!
++ No garantees are made about probe compatibility between versions of
++ CPython. DTrace scripts can stop working or work incorrectly without
++ warning when changing CPython versions.
++
++The :mod:`dtrace` module defines the following variable:
++
++
++.. data:: available
++
++ The variable will be ``True`` if the current CPython interpreter was
++ compiled with DTrace probe support. ``False`` if not.
++
++
++DTrace probes
++-------------
++
++DTrace scripts are run externally to CPython. DTrace probes export
++selected events inside CPython interpreter in order to make them
++accessible to external scripts.
++
++The probes are exported through the "python" provider. The available
++probes are defined in the file :file:`Include/pydtrace.d`.
++
++To learn how to use DTrace, read `DTrace User Guide
++<http://docs.oracle.com/cd/E19253-01/819-5488/>`_.
++
++.. opcode:: function-entry (arg0, arg1, arg2)
++
++ Fires when python code enters a new function. *arg0* is sourcecode
++ file path, *arg1* is the name of the funcion called, and *arg2* is
++ line number.
++
++ The probe is not fired if Python code calls C functions.
++
++.. opcode:: function-return (arg0, arg1, arg2)
++
++ Fires when Python code finishes execution of a function. Parameters
++ are the same as in ``function-entry``.
++
++ The probe is not fired if the finishing function is written in C.
++
++.. opcode:: line (arg0, arg1, arg2)
++
++ Fires when Python code changes the execution line. Parameters are the
++ same as in ``function-entry``.
++
++ The probe is not fired in C functions.
++
++.. opcode:: gc-start (arg0)
++
++ Fires when the Python interpreter starts a garbage collection cycle.
++ *arg0* is the generation to scan, like :func:`gc.collect()`.
++
++.. opcode:: gc-done (arg0)
++
++ Fires when the Python interpreter finishes a garbage collection
++ cycle. *arg0* is the number of collected objects.
++
++.. opcode:: instance-new-start (arg0, arg1)
++
++ Fires when an object instanciation starts. *arg0* is the class name,
++ *arg1* is the filename where the class is defined.
++
++ The probe is not fired for most C code object creations.
++
++.. opcode:: instance-new-done (arg0, arg1)
++
++ Fires when an object instanciation finishes. Parameters are the same
++ as in ``instance-new-done``.
++
++ The probe is not fired for most C code object creations.
++
++.. opcode:: instance-delete-start (arg0, arg1)
++
++ Fires when an object instance is going to be destroyed. Parameters
++ are the same as in ``instance-new-done``.
++
++ The probe is not fired for most C code object destructions.
++
++.. opcode:: instance-delete-done (arg0, arg1)
++
++ Fires when an object instance has been destroyed. parameters are the
++ same as in ``instance-new-done``.
++
++ Between an ``instance-delete-start`` and corresponding
++ ``instance-delete-done`` others probes can fire if, for instance,
++ deletion of an instance creates a deletion cascade.
++
++ The probe is not fired for most C code object destructions.
++
++
++Python stack
++------------
++
++When a DTrace probe is fired, the DTrace script can examine the stack.
++Since CPython is a Python interpreter coded in C, the stack will show C
++functions, with no direct relation to the Python code currently being
++executed.
++
++Using the special "jstack()" DTrace function, the user will be given
++hints about the python program stack, if possible. In particular, the
++augmented stack will show python function calls, filename, name
++of the function or method, and the line number.
++
++DTrace scripts examples
++-----------------------
++
++DTrace python provider is suffixed by the pid of the process to monitor.
++In the examples, the pid will be 9876.
++
++Show the time spent doing garbage collection (in nanoseconds)::
++
++ python9876:::gc-start
++ {
++ self->t = timestamp;
++ }
++
++ python9876:::gc-done
++ /self->t/
++ {
++ printf("%d", timestamp-self->t);
++ self->t = 0;
++ }
++
++Count how many instances are created of each class::
++
++ python9876:::instance-new-start
++ {
++ @v[copyinstr(arg1), copyinstr(arg0)] = count();
++ }
++
++Observe time spent in object destruction, useful if datastructures are
++complicated and deletion of an object can create a cascade effect::
++
++ python9876:::instance-delete-start
++ /self->t==0/
++ {
++ self->t = timestamp;
++ self->level = 0;
++ }
++
++ python9876:::instance-delete-start
++ /self->t/
++ {
++ self->level += 1;
++ }
++
++ python9876:::instance-delete-done
++ /(self->level) && (self->t)/
++ {
++ self->level -= 1;
++ }
++
++ python9876:::instance-delete-done
++ /(self->level==0) && (self->t)/
++ {
++ @time = quantize(timestamp-self->t);
++ self->t = 0;
++ }
++
++To know which python source code lines create new TCP/IP connections::
++
++ pid9876::sock_connect:entry
++ {
++ @conn[jstack()] = count();
++ }
++
+--- Python-3.5.0a4/Include/code.h.~1~ 2015-04-20 00:37:51.000000000 -0700
++++ Python-3.5.0a4/Include/code.h 2015-04-20 12:35:52.053616933 -0700
[email protected]@ -7,6 +7,8 @@
+ extern "C" {
+ #endif
+
++#include "pyconfig.h"
++
+ /* Bytecode object */
+ typedef struct {
+ PyObject_HEAD
[email protected]@ -33,6 +35,9 @@
+ int co_firstlineno; /* first source line number */
+ PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
+ Objects/lnotab_notes.txt for details. */
++#ifdef WITH_DTRACE
++ unsigned short *co_linenos; /* dtrace stack helper */
++#endif
+ void *co_zombieframe; /* for optimization only (see frameobject.c) */
+ PyObject *co_weakreflist; /* to support weakrefs to code objects */
+ } PyCodeObject;
+--- /dev/null
++++ Python-3.4.0/Include/pydtrace.d
[email protected]@ -0,0 +1,177 @@
++provider python {
++ probe function__entry(const char *, const char *, int);
++ probe function__return(const char *, const char *, int);
++ probe instance__new__start(const char *, const char *);
++ probe instance__new__done(const char *, const char *);
++ probe instance__delete__start(const char *, const char *);
++ probe instance__delete__done(const char *, const char *);
++ probe line(const char *, const char *, int);
++ probe gc__start(int);
++ probe gc__done(long);
++};
++
++#pragma D attributes Evolving/Evolving/Common provider python provider
++#pragma D attributes Private/Private/Common provider python module
++#pragma D attributes Private/Private/Common provider python function
++#pragma D attributes Evolving/Evolving/Common provider python name
++#pragma D attributes Evolving/Evolving/Common provider python args
++
++
++
++#ifdef PYDTRACE_STACK_HELPER
++/*
++ * Python ustack helper. This relies on the first argument (PyFrame *) being
++ * on the stack; see Python/ceval.c for the contortions we go through to ensure
++ * this is the case.
++ *
++ * On x86, the PyFrame * is two slots up from the frame pointer; on SPARC, it's
++ * eight.
++ *
++ * Some details about this in "Python and DTrace in build 65":
++ * http://blogs.oracle.com/levon/entry/python_and_dtrace_in_build
++ */
++
++/*
++ * Yes, this is as gross as it looks. DTrace cannot handle static functions,
++ * and our stat_impl.h has them in ILP32.
++ */
++#define _SYS_STAT_H
++
++/*
++** When compiling in 32 bits:
++** - Early inclusion to avoid problems with
++** _FILE_OFFSET_BITS redefined.
++** - Also, we must "undef" _POSIX_PTHREAD_SEMANTICS
++** to avoid error compiling this source.
++*/
++#include "pyconfig.h"
++#undef _POSIX_PTHREAD_SEMANTICS
++
++#include <stdio.h>
++#include <sys/types.h>
++
++#include "pyport.h"
++#include "pyatomic.h"
++/* "string" type is used in dtrace */
++#define string stringDTRACE
++#include "object.h"
++#include "pystate.h"
++#include "pyarena.h"
++#include "pythonrun.h"
++#include "compile.h"
++#include "frameobject.h"
++/* Avoid a compile error because a symbol (equivalent) redefinition */
++#undef __STDC__
++/* "self" has an special meaning for dtrace */
++#define self selfDTRACE
++#include "unicodeobject.h"
++#undef string
++#undef self
++
++#include "pydtrace_offsets.h"
++
++#if defined(__i386)
++#define startframe PyEval_EvalFrameEx
++#define endframe AFTER_PyEval_EvalFrameEx
++#elif defined(__amd64)
++#define startframe PyEval_EvalFrameExReal
++#define endframe AFTER_PyEval_EvalFrameExReal
++#elif defined(__sparc)
++#define startframe PyEval_EvalFrameExReal
++#define endframe AFTER_PyEval_EvalFrameExReal
++#endif
++
++#ifdef __sparcv9
++#define STACK_BIAS (2048-1)
++#else
++#define STACK_BIAS 0
++#endif
++
++#define at_evalframe(addr) \
++ ((uintptr_t)addr >= ((uintptr_t)&``startframe) && \
++ (uintptr_t)addr < ((uintptr_t)&``endframe))
++#define probe dtrace:helper:ustack:
++#define print_result(r) (r)
++
++#if defined(__i386) || defined(__amd64)
++#define frame_ptr_addr ((uintptr_t)arg1 + sizeof(uintptr_t) * 2)
++#elif defined(__sparc)
++#define frame_ptr_addr ((uintptr_t)arg1 + STACK_BIAS + sizeof(uintptr_t) * 8)
++#else
++#error unknown architecture
++#endif
++
++/* startframe and endframe are macro-expansions */
++extern uintptr_t startframe;
++extern uintptr_t endframe;
++
++
++#define copyin_obj(addr, obj) ((obj *)copyin((uintptr_t)(addr), sizeof(obj)))
++
++/*
++** Check if the string is ASCII. Don't use bitfields, because the
++** packing in GCC and D are different. BEWARE!!!.
++** The size of the structures are also different!. That is the reason for
++** the negative offset. BEWARE!!!
++*/
++#define pystr_len(addr) ((*(((char *)addr)+PYDTRACE_ASCII_OFFSET)) & PYDTRACE_ASCII_MASK ? \
++ (addr)->_base.length : \
++ *(Py_ssize_t *)(((char *)(addr)) + PYDTRACE_UTF8_LENGTH_OFFSET))
++#define pystr_addr(addr, addr2) ((*(((char *)addr)+PYDTRACE_ASCII_OFFSET)) & PYDTRACE_ASCII_MASK ? \
++ (char *)(((char *)(addr2)) + PYDTRACE_PyASCIIObject_SIZE) : \
++ (char *)*(uintptr_t *)(((char *)(addr)) + PYDTRACE_UTF8_OFFSET))
++
++#define add_digit(nr, div) (((nr) / div) ? \
++ (this->result[this->pos++] = '0' + (((nr) / div) % 10)) : \
++ (this->result[this->pos] = '\0'))
++#define add_char(c) (this->result[this->pos++] = c)
++
++probe /at_evalframe(arg0)/
++{
++ this->framep = *(uintptr_t *)copyin(frame_ptr_addr, sizeof(uintptr_t));
++ this->frameo = copyin_obj(this->framep, PyFrameObject);
++ this->codep = this->frameo->f_code;
++ this->codeo = copyin_obj(this->codep, PyCodeObject);
++ /* If we just enter a function, show the definition line */
++ this->lineno = this->codeo->co_firstlineno +
++ (this->frameo->f_lasti == -1 ? 0 :
++ *copyin_obj(this->codeo->co_linenos + this->frameo->f_lasti,
++ unsigned short));
++ this->filenameo = copyin_obj(this->codeo->co_filename, PyCompactUnicodeObject);
++ this->len_filename = pystr_len(this->filenameo);
++ this->nameo = copyin_obj(this->codeo->co_name, PyCompactUnicodeObject);
++ this->len_name = pystr_len(this->nameo);
++ this->len = 1 + (this->len_filename) + 1 + 5 + 2 +
++ (this->len_name) + 1 + 1;
++
++ this->result = (char *)alloca(this->len);
++ this->pos = 0;
++ add_char('@');
++
++ copyinto((uintptr_t)pystr_addr(this->filenameo, this->codeo->co_filename), this->len_filename, this->result+this->pos);
++ this->pos += this->len_filename;
++
++ add_char(':');
++ add_digit(this->lineno, 10000);
++ add_digit(this->lineno, 1000);
++ add_digit(this->lineno, 100);
++ add_digit(this->lineno, 10);
++ add_digit(this->lineno, 1);
++ add_char(' ');
++ add_char('(');
++
++ copyinto((uintptr_t)pystr_addr(this->nameo, this->codeo->co_name), this->len_name, this->result+this->pos);
++ this->pos += this->len_name;
++
++ add_char(')');
++ this->result[this->pos] = '\0';
++ print_result(stringof(this->result));
++}
++
++probe /!at_evalframe(arg0)/
++{
++ NULL;
++}
++
++#endif /* PYDTRACE_STACK_HELPER */
++
+--- /dev/null
++++ Python-3.4.0/Include/pydtrace_offsets.c
[email protected]@ -0,0 +1,40 @@
++#include "Python.h"
++#include "unicodeobject.h"
++#include <stdlib.h>
++#include <stdio.h>
++
++int main(int argc, const char* argv[]) {
++ PyCompactUnicodeObject o;
++ unsigned char *p = (unsigned char *)(&o);
++
++ if (argc != 3) {
++ printf("Parameter number incorrect\n");
++ exit(1);
++ }
++
++ memset(&o, 0, sizeof(o));
++ o._base.state.ascii = 1;
++ while (!*p) p++;
++
++ printf("/* File autogenerated. DO NOT MODIFY MANUALLY */\n");
++ printf("\n");
++ printf("#ifndef PYDTRACE_OFFSETS_H\n");
++ printf("#define PYDTRACE_OFFSETS_H\n");
++ printf("\n");
++ printf("#define PYDTRACE_ASCII_OFFSET %d\n",
++ p-(unsigned char *)(&o));
++ printf("#define PYDTRACE_ASCII_MASK %d\n", *p);
++ printf("#define PYDTRACE_PyASCIIObject_SIZE %d\n",
++ sizeof(PyASCIIObject));
++ printf("#define PYDTRACE_UTF8_LENGTH_OFFSET %d\n",
++ offsetof(PyCompactUnicodeObject, utf8_length));
++ printf("#define PYDTRACE_UTF8_OFFSET %d\n",
++ offsetof(PyCompactUnicodeObject, utf8));
++ printf("\n");
++ printf("#define AFTER_PyEval_EvalFrameEx %s\n", argv[1]);
++ printf("#define AFTER_PyEval_EvalFrameExReal %s\n", argv[2]);
++ printf("\n");
++ printf("#endif\n");
++ return 0;
++}
++
+new file mode 100755
+--- /dev/null
++++ Python-3.4.0/Include/pydtrace_offsets.sh
[email protected]@ -0,0 +1,32 @@
++#!/bin/sh
++
++DTRACE_NM=$1
++CEVAL_O=$2
++PYDTRACE_OFFSETS=$3
++if test "$DTRACE_NM" = "OTHER" ; then
++ $PYDTRACE_OFFSETS \
++ "`nm -n $CEVAL_O | grep \" T \" | \
++ sed -n \"/ T PyEval_EvalFrameEx$/{n;p;}\" | \
++ sed \"s/.* T \(.*\)$/\1/\"`" \
++ "`nm -n $CEVAL_O | grep \" T \" | \
++ sed -n \"/ T PyEval_EvalFrameExReal$/{n;p;}\" | \
++ sed \"s/.* T \(.*\)$/\1/\"`"
++fi
++if test "$DTRACE_NM" = "SOLARIS" ; then
++ $PYDTRACE_OFFSETS \
++ "`/usr/ccs/bin/nm -n $CEVAL_O | \
++ /usr/bin/grep \"\\|FUNC \\|\" | \
++ /usr/bin/grep -v \"\\|IGNORE \\|\" | \
++ /usr/bin/grep -v \"\\|UNDEF \\|\" | \
++ /usr/bin/tr -d \"\\[\\]\\|\" | sort -n | \
++ sed -n \"/ PyEval_EvalFrameEx$/{n;p;}\" | \
++ sed \"s/.* \([a-zA-Z0-9_]*\)$/\1/\"`" \
++ "`/usr/ccs/bin/nm -n $CEVAL_O | \
++ /usr/bin/grep \"\\|FUNC \\|\" | \
++ /usr/bin/grep -v \"\\|UNDEF \\|\" | \
++ /usr/bin/grep -v \"\\|IGNORE \\|\" | \
++ /usr/bin/tr -d \"\\[\\]\\|\" | sort -n | \
++ sed -n \"/ PyEval_EvalFrameExReal$/{n;p;}\" | \
++ sed \"s/.* \([a-zA-Z0-9_]*\)$/\1/\"`"
++fi
++
+--- /dev/null
++++ Python-3.4.0/Lib/test/dtrace_sample.py
[email protected]@ -0,0 +1,80 @@
++# Sample script for use by test_dtrace.py
++# DO NOT MODIFY THIS FILE IN ANY WAY WITHOUT UPDATING test_dtrace.py!!!!!
++
++import gc
++
++def function_1() :
++ pass
++
++# Check stacktrace
++def function_2() :
++ function_1()
++
++# CALL_FUNCTION_VAR
++def function_3(dummy, dummy2) :
++ pass
++
++# CALL_FUNCTION_KW
++def function_4(**dummy) :
++ pass
++
++# CALL_FUNCTION_VAR_KW
++def function_5(dummy, dummy2, **dummy3) :
++ pass
++
++def test_entry_return_and_stack() :
++ function_1()
++ function_2()
++ function_3(*(1,2))
++ function_4(**{"test":42})
++ function_5(*(1,2), **{"test":42})
++
++def test_line() :
++ a = 1 # Preamble
++ for i in range(2) :
++ a = i
++ b = i+2
++ c = i+3
++ d = a + b +c
++ a = 1 # Epilogue
++
++def test_unicode_entry_return_and_stack() :
++ def únÃcódé() :
++ pass
++ únÃcódé()
++
++def test_instance_creation_destruction() :
++ class old_style_class() :
++ pass
++ class new_style_class(object) :
++ pass
++
++ a = old_style_class()
++ del a
++ gc.collect()
++ b = new_style_class()
++ del b
++ gc.collect()
++
++ a = old_style_class()
++ del old_style_class
++ gc.collect()
++ b = new_style_class()
++ del new_style_class
++ gc.collect()
++ del a
++ gc.collect()
++ del b
++ gc.collect()
++
++def test_garbage_collection() :
++ gc.collect()
++
++
++if __name__ == "__main__":
++ test_entry_return_and_stack()
++ test_line()
++ test_unicode_entry_return_and_stack()
++ test_instance_creation_destruction()
++ test_garbage_collection()
++
+--- /dev/null
++++ Python-3.4.0/Lib/test/test_dtrace.py
[email protected]@ -0,0 +1,447 @@
++import sys, unittest, subprocess, os.path, dis, types, re
++import dtrace
++from test.support import TESTFN, run_unittest, findfile
++
++sample = os.path.abspath(findfile("dtrace_sample.py"))
++if not dtrace.available :
++ raise unittest.SkipTest("dtrace support not compiled in")
++
++def normalize(data) :
++ # DTRACE keeps a per-CPU buffer, and when showing the fired probes,
++ # buffers are concatenated. So if the operating system moves our
++ # thread around, the straight result can be "non causal".
++ # So we add timestamps to the probe firing, and sort by that field.
++
++ result = data if isinstance(data, str) else data.decode("ascii")
++ # When compiling with '--with-pydebug'
++ result = "".join(re.split("\[[0-9]+ refs\]", result))
++
++ try :
++ result = [i.split("\t") \
++ for i in result.replace("\r", "").split("\n") if len(i)]
++ result.sort(key = lambda i: int(i[0]))
++ result = "".join((i[1] for i in result))
++ result = result.replace(" ", "")
++ except :
++ # If something goes wrong, rebuild the value so we can see the
++ # real result when the assert fails.
++ result = data if isinstance(data, str) else data.decode("ascii")
++ result = result.replace("\r", "").replace("\n", "")
++ return result
++
++dscript = """
++pid$target::PyEval_EvalCode:entry
++"""
++dscript = dscript.replace("\r", "").replace("\n", "")
++result, _ = subprocess.Popen(["dtrace", "-q", "-l", "-n", dscript,
++ "-c", "%s %s" %(sys.executable, sample)], stdout=subprocess.PIPE,
++ stderr=subprocess.STDOUT).communicate()
++if result.decode("ascii").split("\n")[1].split()[-2:] != \
++ ["PyEval_EvalCode", "entry"] :
++ result2 = repr(result)
++ raise unittest.SkipTest("dtrace seems not to be working. " + \
++ "Please, check your privileges. " +
++ "Result: " +result2)
++
++class DTraceTestsNormal(unittest.TestCase) :
++ def setUp(self) :
++ self.optimize = False
++
++ def test_function_entry_return(self) :
++ dscript = """
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_entry_return_and_stack")/
++{
++ self->trace = 1;
++}
++python$target:::function-entry,python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") && (self->trace)/
++{
++ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
++ probename, copyinstr(arg0),
++ copyinstr(arg1), arg2);
++}
++python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_entry_return_and_stack")/
++{
++ self->trace = 0;
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ **function-entry*%(path)s*test_entry_return_and_stack*25
++ **function-entry*%(path)s*function_1*6
++ **function-return*%(path)s*function_1*7
++ **function-entry*%(path)s*function_2*10
++ **function-entry*%(path)s*function_1*6
++ **function-return*%(path)s*function_1*7
++ **function-return*%(path)s*function_2*11
++ **function-entry*%(path)s*function_3*14
++ **function-return*%(path)s*function_3*15
++ **function-entry*%(path)s*function_4*18
++ **function-return*%(path)s*function_4*19
++ **function-entry*%(path)s*function_5*22
++ **function-return*%(path)s*function_5*23
++ **function-return*%(path)s*test_entry_return_and_stack*30
++ """ %{"path":sample}
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = normalize(actual_result)
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++ @unittest.skipIf(sys.platform == 'darwin',
++ "MacOS X doesn't support jstack()")
++ def test_stack(self) :
++ dscript = """
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_entry_return_and_stack")/
++{
++ self->trace = 1;
++}
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") && (self->trace)/
++{
++ printf("[x]");
++ jstack();
++}
++python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_entry_return_and_stack")/
++{
++ self->trace = 0;
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ [x]
++ [%(path)s:25(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:6(function_1)]
++ [%(path)s:26(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:10(function_2)]
++ [%(path)s:27(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:6(function_1)]
++ [%(path)s:11(function_2)]
++ [%(path)s:27(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:14(function_3)]
++ [%(path)s:28(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:18(function_4)]
++ [%(path)s:29(test_entry_return_and_stack)]
++ [x]
++ [%(path)s:22(function_5)]
++ [%(path)s:30(test_entry_return_and_stack)]
++ """ %{"path":sample}
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = actual_result.decode("ascii")
++ # When compiling with '--with-pydebug'
++ actual_result = "".join(re.split("\[[0-9]+ refs\]", actual_result))
++
++ actual_result = [i for i in actual_result.split("\n") \
++ if (("[" in i) and not i.endswith(" (<module>) ]"))]
++ actual_result = "".join(actual_result)
++ actual_result = actual_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++ def test_garbage_collection(self) :
++ dscript = """
++python$target:::gc-start,python$target:::gc-done
++{
++ printf("%d\t**%s(%ld)\\n", timestamp, probename, arg0);
++}
++"""
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = normalize(actual_result)
++ for i in range(10) :
++ actual_result = actual_result.replace(str(i), "")
++ expected_result = "**gc-start()**gc-done()" * \
++ actual_result.count("**gc-start()**")
++
++ self.assertEqual(actual_result, expected_result)
++
++ def test_verify_opcodes(self) :
++ # Verify that we are checking:
++ opcodes = set(["CALL_FUNCTION", "CALL_FUNCTION_VAR",
++ "CALL_FUNCTION_KW", "CALL_FUNCTION_VAR_KW"])
++ with open(sample, encoding="utf-8") as f :
++ obj = compile(f.read(), "sample", "exec")
++ class dump() :
++ def __init__(self) :
++ self.buf = []
++ def write(self, v) :
++ self.buf.append(v)
++
++ dump = dump()
++ stdout = sys.stdout
++ sys.stdout = dump
++ for i in obj.co_consts :
++ if isinstance(i, types.CodeType) and \
++ (i.co_name == 'test_entry_return_and_stack') :
++ dis.dis(i)
++ sys.stdout = stdout
++ dump = "\n".join(dump.buf)
++ dump = dump.replace("\r", "").replace("\n", "").split()
++ for i in dump :
++ opcodes.discard(i)
++ # Are we verifying all the relevant opcodes?
++ self.assertEqual(set(), opcodes) # Are we verifying all opcodes?
++
++ def test_line(self) :
++ dscript = """
++python$target:::line
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_line")/
++{
++ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
++ probename, copyinstr(arg0),
++ copyinstr(arg1), arg2);
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ **line*%(path)s*test_line*33
++ **line*%(path)s*test_line*34
++ **line*%(path)s*test_line*35
++ **line*%(path)s*test_line*36
++ **line*%(path)s*test_line*37
++ **line*%(path)s*test_line*38
++ **line*%(path)s*test_line*34
++ **line*%(path)s*test_line*35
++ **line*%(path)s*test_line*36
++ **line*%(path)s*test_line*37
++ **line*%(path)s*test_line*38
++ **line*%(path)s*test_line*34
++ **line*%(path)s*test_line*39
++ """ %{"path":sample}
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = normalize(actual_result)
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++ def test_instance_creation_destruction(self) :
++ dscript = """
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_instance_creation_destruction")/
++{
++ self->trace = 1;
++}
++
++python$target:::instance-new-start,
++python$target:::instance-new-done,
++python$target:::instance-delete-start,
++python$target:::instance-delete-done
++/self->trace/
++{
++ printf("%%d\t**%%s* (%%s.%%s)\\n", timestamp,
++ probename, copyinstr(arg1), copyinstr(arg0));
++}
++
++python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_instance_creation_destruction")/
++{
++ self->trace = 0;
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ **instance-new-start*(__main__.old_style_class)
++ **instance-new-done*(__main__.old_style_class)
++ **instance-delete-start*(__main__.old_style_class)
++ **instance-delete-done*(__main__.old_style_class)
++ **instance-new-start*(__main__.new_style_class)
++ **instance-new-done*(__main__.new_style_class)
++ **instance-delete-start*(__main__.new_style_class)
++ **instance-delete-done*(__main__.new_style_class)
++ **instance-new-start*(__main__.old_style_class)
++ **instance-new-done*(__main__.old_style_class)
++ **instance-new-start*(__main__.new_style_class)
++ **instance-new-done*(__main__.new_style_class)
++ **instance-delete-start*(__main__.old_style_class)
++ **instance-delete-done*(__main__.old_style_class)
++ **instance-delete-start*(__main__.new_style_class)
++ **instance-delete-done*(__main__.new_style_class)
++ """
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = normalize(actual_result)
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++ def test_unicode_function_entry_return(self) :
++ dscript = """
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
++{
++ self->trace = 1;
++}
++python$target:::function-entry,python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") && (self->trace)/
++{
++ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
++ probename, copyinstr(arg0),
++ copyinstr(arg1), arg2);
++}
++python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
++{
++ self->trace = 0;
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ **function-entry*%(path)s*test_unicode_entry_return_and_stack*41
++ **function-entry*%(path)s*únÃcódé*42
++ **function-return*%(path)s*únÃcódé*43
++ **function-return*%(path)s*test_unicode_entry_return_and_stack*44
++ """ %{"path":sample}
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = actual_result.decode("utf8")
++ actual_result = normalize(actual_result)
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++ @unittest.skipIf(sys.platform == 'darwin',
++ "MacOS X doesn't support jstack()")
++ def test_unicode_stack(self) :
++ dscript = """
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
++{
++ self->trace = 1;
++}
++python$target:::function-entry
++/(copyinstr(arg0)=="%(path)s") && (self->trace)/
++{
++ printf("[x]");
++ jstack();
++}
++python$target:::function-return
++/(copyinstr(arg0)=="%(path)s") &&
++(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
++{
++ self->trace = 0;
++}
++""" %{"path":sample}
++
++ dscript = dscript.replace("\r", "").replace("\n", "")
++ expected_result = """
++ [x]
++ [%(path)s:41(test_unicode_entry_return_and_stack)]
++ [x]
++ [%(path)s:42(únÃcódé)]
++ [%(path)s:44(test_unicode_entry_return_and_stack)]
++ """ %{"path":sample}
++
++ command = "%s %s" %(sys.executable, sample)
++ if self.optimize :
++ command = "%s -OO %s" %(sys.executable, sample)
++ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
++ dscript,
++ "-c", command],
++ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
++
++ actual_result = actual_result.decode("utf8")
++ # When compiling with '--with-pydebug'
++ actual_result = "".join(re.split("\[[0-9]+ refs\]", actual_result))
++
++ actual_result = [i for i in actual_result.split("\n") \
++ if (("[" in i) and not i.endswith(" (<module>) ]"))]
++ actual_result = "".join(actual_result)
++ actual_result = actual_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ expected_result = expected_result.replace("\r", "").replace("\n",
++ "").replace(" ", "")
++ self.assertEqual(actual_result, expected_result)
++
++
++
++# This class try to verify that dtrace probes
++# are still working with optimizations enabled in the bytecode.
++#
++# Some tests will not actually verify it. For instance,
++# source code compilation follows optimization status of
++# current working Python. So, you should run the test
++# both with an optimizing and a non optimizing Python.
++class DTraceTestsOptimize(DTraceTestsNormal) :
++ def setUp(self) :
++ self.optimize = True
++
++
++def test_main():
++ run_unittest(DTraceTestsNormal)
++ run_unittest(DTraceTestsOptimize)
++
++if __name__ == '__main__':
++ test_main()
++
+--- Python-3.5.0a4/Lib/test/test_sys.py.~1~ 2015-04-20 00:37:52.000000000 -0700
++++ Python-3.5.0a4/Lib/test/test_sys.py 2015-04-20 12:38:22.235939749 -0700
[email protected]@ -829,6 +829,7 @@
+ self.assertEqual(sys.getsizeof(True, -1), size('') + self.longdigit)
+
+ def test_objecttypes(self):
++ import dtrace
+ # check all types defined in Objects/
+ size = test.support.calcobjsize
+ vsize = test.support.calcvobjsize
[email protected]@ -857,13 +858,17 @@
+ return inner
+ check(get_cell().__closure__[0], size('P'))
+ # code
+- check(get_cell().__code__, size('5i9Pi3P'))
+- check(get_cell.__code__, size('5i9Pi3P'))
++ if dtrace.available :
++ code = '5i9PiPH2P'
++ else :
++ code = '5i9Pi3P'
++ check(get_cell().__code__, size(code))
++ check(get_cell.__code__, size(code))
+ def get_cell2(x):
+ def inner():
+ return x
+ return inner
+- check(get_cell2.__code__, size('5i9Pi3P') + 1)
++ check(get_cell2.__code__, size(code) + 1)
+ # complex
+ check(complex(0,1), size('2d'))
+ # method_descriptor (descriptor object)
+--- Python-3.5.0rc2/Makefile.pre.in.~1~ 2015-08-25 10:19:13.000000000 -0700
++++ Python-3.5.0rc2/Makefile.pre.in 2015-09-02 11:27:31.510492090 -0700
[email protected]@ -52,6 +52,13 @@
+ # Use this to make a link between python$(VERSION) and python in $(BINDIR)
+ LN= @[email protected]
+
++DTRACE= @[email protected]
++DFLAGS= @[email protected]
++DTRACEOBJS= @[email protected]
++DTRACE_NM= @[email protected]
++DTRACE_LINKER= @[email protected]
++
++
+ # Portable install script (configure doesn't always guess right)
+ INSTALL= @[email protected]
+ [email protected][email protected]
[email protected]@ -596,7 +603,7 @@
+ $(AR) $(ARFLAGS) [email protected] $(MODOBJS)
+ $(RANLIB) [email protected]
+
+-libpython$(LDVERSION).so: $(LIBRARY_OBJS)
++libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACEOBJS)
+ if test $(INSTSONAME) != $(LDLIBRARY); then \
+ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(LN) -f $(INSTSONAME) [email protected]; \
[email protected]@ -607,9 +614,8 @@
+ libpython3.so: libpython$(LDVERSION).so
+ $(BLDSHARED) $(NO_AS_NEEDED) -o [email protected] -Wl,[email protected] $^
+
+-libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
+- $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o [email protected] $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+-
++libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) $(DTRACEOBJS)
++ $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o [email protected] $(LIBRARY_OBJS) $(DTRACEOBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
+
+ libpython$(VERSION).sl: $(LIBRARY_OBJS)
+ $(LDSHARED) -o [email protected] $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
[email protected]@ -714,12 +720,18 @@
+ $(MODULE_OBJS) \
+ $(SIGNAL_OBJS) \
+ $(MODOBJS) \
++ $(DTRACEOBJS) \
+ $(srcdir)/Modules/getbuildinfo.c
+ $(CC) -c $(PY_CORE_CFLAGS) \
+ -DHGVERSION="\"`LC_ALL=C $(HGVERSION)`\"" \
+ -DHGTAG="\"`LC_ALL=C $(HGTAG)`\"" \
+ -DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \
+ -o [email protected] $(srcdir)/Modules/getbuildinfo.c
++ if test "$(DTRACEOBJS)" != "" ; then \
++ $(DTRACE_LINKER) --relocatable \
++ [email protected] $(DTRACEOBJS) -o [email protected] ; \
++ mv [email protected] [email protected] ; \
++ fi;
+
+ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
+ $(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
[email protected]@ -853,6 +865,46 @@
+ Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py
+ $(PYTHON) $(srcdir)/Objects/typeslots.py < $(srcdir)/Include/typeslots.h > Objects/typeslots.inc
+
++$(srcdir)/Include/pydtrace.h: $(srcdir)/Include/pydtrace.d
++ if test "$(DTRACE)" != "" ; then \
++ $(DTRACE) -o [email protected] $(DFLAGS) \
++ -C -h -s $(srcdir)/Include/pydtrace.d ; \
++ else touch [email protected] ; \
++ fi;
++
++$(srcdir)/Include/pydtrace_offsets.h: $(srcdir)/Include/pydtrace_offsets.c Python/ceval.o
++ $(CC) $(PY_CORE_CFLAGS) -o $(srcdir)/Include/pydtrace_offsets \
++ $(srcdir)/Include/pydtrace_offsets.c
++ $(srcdir)/Include/pydtrace_offsets.sh $(DTRACE_NM) \
++ Python/ceval.o $(srcdir)/Include/pydtrace_offsets > \
++ $(srcdir)/Include/pydtrace_offsets.h
++
++Python/ceval.o: Include/pydtrace.h
++Modules/gcmodule.o: Include/pydtrace.h
++Objects/typeobject.o: Include/pydtrace.h
++
++Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(srcdir)/Include/pydtrace_offsets.h \
++ Python/ceval.o Modules/gcmodule.o Objects/typeobject.o
++ # We do the "touch" game to break a circular dependency between
++ # "Python/ceval.o" and "Include/pydtrace_offsets.h".
++ if test "$(DTRACE)" != "" ; then \
++ touch -r Python/ceval.o Python/ceval.o.ts_dtrace ; \
++ touch -r Modules/gcmodule.o Modules/gcmodule.o.ts_dtrace ; \
++ touch -r Objects/typeobject.o Objects/typeobject.o.ts_dtrace ; \
++ $(DTRACE) -o [email protected] -DPYDTRACE_STACK_HELPER \
++ $(DFLAGS) $(PY_CPPFLAGS) \
++ -C -G -s $(srcdir)/Include/pydtrace.d \
++ Python/ceval.o Modules/gcmodule.o \
++ Objects/typeobject.o; \
++ touch -r Python/ceval.o.ts_dtrace Python/ceval.o ; \
++ touch -r Modules/gcmodule.o.ts_dtrace Modules/gcmodule.o ; \
++ touch -r Objects/typeobject.o.ts_dtrace Objects/typeobject.o ; \
++ rm Python/ceval.o.ts_dtrace ; \
++ rm Modules/gcmodule.o.ts_dtrace ; \
++ rm Objects/typeobject.o.ts_dtrace ; \
++ else touch [email protected] ; \
++ fi;
++
+ ############################################################################
+ # Header files
+
[email protected]@ -1567,6 +1619,11 @@
+ find build -name '*.py[co]' -exec rm -f {} ';' || true
+ -rm -f pybuilddir.txt
+ -rm -f Lib/lib2to3/*Grammar*.pickle
++ rm -f Include/pydtrace.h
++ rm -f Include/pydtrace_offsets Include/pydtrace_offsets.h
++ rm -f Python/ceval.o.ts_dtrace
++ rm -f Modules/gcmodule.o.ts_dtrace
++ rm -f Objects/typeobject.o.ts_dtrace
+ -rm -f Programs/_testembed Programs/_freeze_importlib
+
+ profile-removal:
[email protected]@ -1598,6 +1655,11 @@
+ -o -name '*.orig' -o -name '*.rej' \
+ -o -name '*.bak' ')' \
+ -exec rm -f {} ';'
++ rm -f Include/pydtrace.h
++ rm -f Include/pydtrace_offsets Include/pydtrace_offsets.h
++ rm -f Python/ceval.o.ts_dtrace
++ rm -f Modules/gcmodule.o.ts_dtrace
++ rm -f Objects/typeobject.o.ts_dtrace
+
+ # Check for smelly exported symbols (not starting with Py/_Py)
+ smelly: all
+--- Python-3.4.0/Modules/Setup.dist
++++ Python-3.4.0/Modules/Setup.dist
[email protected]@ -390,3 +390,5 @@
+
+ # Another example -- the 'xxsubtype' module shows C-level subtyping in action
+ xxsubtype xxsubtype.c
++
++dtrace dtracemodule.c
+--- /dev/null
++++ Python-3.4.0/Modules/dtracemodule.c
[email protected]@ -0,0 +1,39 @@
++#include "Python.h"
++
++static PyMethodDef dtrace_methods[] = {
++ {NULL, NULL} /* sentinel */
++};
++
++
++static struct PyModuleDef dtracemodule = {
++ PyModuleDef_HEAD_INIT,
++ "dtrace",
++ NULL,
++ -1,
++ dtrace_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL
++};
++
++PyMODINIT_FUNC
++PyInit_dtrace(void)
++{
++ PyObject *m, *v;
++
++ m = PyModule_Create(&dtracemodule);
++ if (m) {
++#ifdef WITH_DTRACE
++ v = Py_True;
++#else
++ v = Py_False;
++#endif
++ Py_INCREF(v);
++ if (PyModule_AddObject(m, "available", v) < 0) {
++ Py_DECREF(m);
++ return NULL;
++ }
++ }
++ return m;
++}
+--- Python-3.5.0a4/Modules/gcmodule.c.~1~ 2015-04-20 00:37:52.000000000 -0700
++++ Python-3.5.0a4/Modules/gcmodule.c 2015-04-20 12:54:18.784913115 -0700
[email protected]@ -27,6 +27,10 @@
+ #include "frameobject.h" /* for PyFrame_ClearFreeList */
+ #include "pytime.h" /* for _PyTime_GetMonotonicClock() */
+
++#ifdef WITH_DTRACE
++#include "pydtrace.h"
++#endif
++
+ /* Get an object's GC head */
+ #define AS_GC(o) ((PyGC_Head *)(o)-1)
+
[email protected]@ -897,7 +901,12 @@
+ /* This is the main function. Read this to understand how the
+ * collection process works. */
+ static Py_ssize_t
+-collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
++#ifdef WITH_DTRACE
++collect2
++#else
++collect
++#endif
++(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
+ int nofail)
+ {
+ int i;
[email protected]@ -1071,6 +1080,50 @@
+ return n+m;
+ }
+
++#ifdef WITH_DTRACE
++static void
++dtrace_gc_start(int collection)
++{
++ PYTHON_GC_START(collection);
++
++ /*
++ * Currently a USDT tail-call will not receive the correct arguments.
++ * Disable the tail call here.
++ */
++#if defined(__sparc)
++ asm("nop");
++#endif
++}
++
++static void
++dtrace_gc_done(Py_ssize_t value)
++{
++ PYTHON_GC_DONE((long) value);
++
++ /*
++ * Currently a USDT tail-call will not receive the correct arguments.
++ * Disable the tail call here.
++ */
++#if defined(__sparc)
++ asm("nop");
++#endif
++}
++
++static Py_ssize_t
++collect(int collection, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
++ int nofail)
++{
++ Py_ssize_t value;
++
++ if (PYTHON_GC_START_ENABLED())
++ dtrace_gc_start(collection);
++ value = collect2(collection, n_collected, n_uncollectable, nofail);
++ if (PYTHON_GC_DONE_ENABLED())
++ dtrace_gc_done(value);
++ return value;
++}
++#endif /* WITH_DTRACE */
++
+ /* Invoke progress callbacks to notify clients that garbage collection
+ * is starting or stopping
+ */
+--- Python-3.4.0/Objects/codeobject.c
++++ Python-3.4.0/Objects/codeobject.c
[email protected]@ -152,6 +152,37 @@
+ co->co_lnotab = lnotab;
+ co->co_zombieframe = NULL;
+ co->co_weakreflist = NULL;
++
++#ifdef WITH_DTRACE
++ /*
++ ** Cache UTF8 internally, available
++ ** for the pythonframe stack walker.
++ */
++ PyUnicode_AsUTF8(filename);
++ PyUnicode_AsUTF8(name);
++
++ i = PyBytes_Size(co->co_code);
++ co->co_linenos = PyMem_Malloc(sizeof(unsigned short) * i);
++ if (co->co_linenos) {
++ unsigned short *p = (unsigned short *)(co->co_linenos);
++ unsigned char *p2 = (unsigned char*)PyBytes_AsString(co->co_lnotab);
++ int size = PyBytes_Size(co->co_lnotab) / 2;
++ int i2;
++ unsigned short offset = 0;
++
++ while (size) {
++ size -= 1;
++ i2 = *p2++;
++ i-=i2;
++ while (i2--)
++ *p++ = offset;
++ offset += *p2++;
++ }
++ while(i--)
++ *p++ = offset;
++ }
++#endif
++
+ return co;
+ }
+
+--- Python-3.5.0rc2/Objects/frameobject.c.~1~ 2015-08-25 10:19:14.000000000 -0700
++++ Python-3.5.0rc2/Objects/frameobject.c 2015-09-02 11:31:53.362348226 -0700
[email protected]@ -737,6 +737,15 @@
+ f->f_executing = 0;
+ f->f_gen = NULL;
+
++#ifdef WITH_DTRACE
++ /*
++ ** Cache UTF8 internally, available
++ ** for the pythonframe stack walker.
++ */
++ PyUnicode_AsUTF8(f->f_code->co_filename);
++ PyUnicode_AsUTF8(f->f_code->co_name);
++#endif
++
+ _PyObject_GC_TRACK(f);
+ return f;
+ }
+--- Python-3.5.0a4/Objects/typeobject.c.~1~ 2015-04-20 00:37:53.000000000 -0700
++++ Python-3.5.0a4/Objects/typeobject.c 2015-04-20 12:55:28.246913689 -0700
[email protected]@ -4,6 +4,10 @@
+ #include "frameobject.h"
+ #include "structmember.h"
+
++#ifdef WITH_DTRACE
++#include "pydtrace.h"
++#endif
++
+ #include <ctype.h>
+
+
[email protected]@ -934,8 +938,29 @@
+ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+ {
+ PyObject *obj;
+- const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
++ size_t size;
++
++#ifdef WITH_DTRACE
++ PyObject *mod;
++ char *mod_name;
++
++ if (PYTHON_INSTANCE_NEW_START_ENABLED()) {
++ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
++ mod = PyDict_GetItemString(type->tp_dict, "__module__");
++ if (mod == NULL || !PyUnicode_Check(mod)) {
++ mod_name = "?";
++ } else {
++ mod_name = PyUnicode_AsUTF8(mod);
++ if (!mod_name)
++ mod_name = "?";
++ }
++ PYTHON_INSTANCE_NEW_START((char *)(type->tp_name), mod_name);
++ }
++ }
++#endif
++
+ /* note that we need to add one, for the sentinel */
++ size = _PyObject_VAR_SIZE(type, nitems+1);
+
+ if (PyType_IS_GC(type))
+ obj = _PyObject_GC_Malloc(size);
[email protected]@ -957,6 +982,23 @@
+
+ if (PyType_IS_GC(type))
+ _PyObject_GC_TRACK(obj);
++
++#ifdef WITH_DTRACE
++ if (PYTHON_INSTANCE_NEW_DONE_ENABLED()) {
++ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
++ mod = PyDict_GetItemString(type->tp_dict, "__module__");
++ if (mod == NULL || !PyUnicode_Check(mod)) {
++ mod_name = "?";
++ } else {
++ mod_name = PyUnicode_AsUTF8(mod);
++ if (!mod_name)
++ mod_name = "?";
++ }
++ PYTHON_INSTANCE_NEW_DONE((char *)(type->tp_name), mod_name);
++ }
++ }
++#endif
++
+ return obj;
+ }
+
[email protected]@ -1077,9 +1119,56 @@
+ return 0;
+ }
+
++#ifdef WITH_DTRACE
++static void subtype_dealloc2(PyObject *); /* Forward declaration */
++
+ static void
+ subtype_dealloc(PyObject *self)
+ {
++ PyObject *mod;
++ char *mod_name;
++ PyTypeObject *type;
++
++ type = Py_TYPE(self);
++ Py_INCREF(type);
++
++ if (PYTHON_INSTANCE_DELETE_START_ENABLED()) {
++ mod = PyDict_GetItemString(type->tp_dict, "__module__");
++ if (mod == NULL || !PyUnicode_Check(mod)) {
++ mod_name = "?";
++ } else {
++ mod_name = PyUnicode_AsUTF8(mod);
++ if (!mod_name)
++ mod_name = "?";
++ }
++ PYTHON_INSTANCE_DELETE_START((char *)(type->tp_name), mod_name);
++ }
++
++ subtype_dealloc2(self);
++
++ if (PYTHON_INSTANCE_DELETE_DONE_ENABLED()) {
++ mod = PyDict_GetItemString(type->tp_dict, "__module__");
++ if (mod == NULL || !PyUnicode_Check(mod)) {
++ mod_name = "?";
++ } else {
++ mod_name = PyUnicode_AsUTF8(mod);
++ if (!mod_name)
++ mod_name = "?";
++ }
++ PYTHON_INSTANCE_DELETE_DONE((char *)(type->tp_name), mod_name);
++ }
++ Py_DECREF(type);
++}
++#endif
++
++static void
++#ifdef WITH_DTRACE
++subtype_dealloc2
++#else
++subtype_dealloc
++#endif
++(PyObject *self)
++{
+ PyTypeObject *type, *base;
+ destructor basedealloc;
+ PyThreadState *tstate = PyThreadState_GET();
+--- Python-3.5.0rc2/Python/ceval.c.~1~ 2015-08-25 10:19:14.000000000 -0700
++++ Python-3.5.0rc2/Python/ceval.c 2015-09-02 11:33:12.745496843 -0700
[email protected]@ -20,6 +20,13 @@
+
+ #include <ctype.h>
+
++#ifdef WITH_DTRACE
++#include "pydtrace.h"
++#else
++/* We can not have conditional compilation inside macros */
++#define PYTHON_LINE_ENABLED() (0)
++#endif
++
+ #ifndef WITH_TSC
+
+ #define READ_TIMESTAMP(var)
[email protected]@ -123,6 +130,12 @@
+ #define CALL_FLAG_VAR 1
+ #define CALL_FLAG_KW 2
+
++#ifdef WITH_DTRACE
++static void maybe_dtrace_line(PyFrameObject *frame,
++ int *instr_lb, int *instr_ub,
++ int *instr_prev);
++#endif
++
+ #ifdef LLTRACE
+ static int lltrace;
+ static int prtrace(PyObject *, char *);
[email protected]@ -782,6 +795,49 @@
+ NULL, NULL);
+ }
+
++#ifdef WITH_DTRACE
++static void
++dtrace_entry(PyFrameObject *f)
++{
++ char *filename;
++ char *name;
++ int lineno;
++
++ filename = PyUnicode_AsUTF8(f->f_code->co_filename);
++ name = PyUnicode_AsUTF8(f->f_code->co_name);
++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
++ PYTHON_FUNCTION_ENTRY(filename, name, lineno);
++
++ /*
++ * Currently a USDT tail-call will not receive the correct arguments.
++ * Disable the tail call here.
++ */
++#if defined(__sparc)
++ asm("nop");
++#endif
++}
++
++static void
++dtrace_return(PyFrameObject *f)
++{
++ char *filename;
++ char *name;
++ int lineno;
++
++ filename = PyUnicode_AsUTF8(f->f_code->co_filename);
++ name = PyUnicode_AsUTF8(f->f_code->co_name);
++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
++ PYTHON_FUNCTION_RETURN(filename, name, lineno);
++
++ /*
++ * Currently a USDT tail-call will not receive the correct arguments.
++ * Disable the tail call here.
++ */
++#if defined(__sparc)
++ asm("nop");
++#endif
++}
++#endif
+
+ /* Interpreter main loop */
+
[email protected]@ -793,8 +849,16 @@
+ return PyEval_EvalFrameEx(f, 0);
+ }
+
++
+ PyObject *
++#if defined(WITH_DTRACE) && defined(__amd64)
++PyEval_EvalFrameExReal(long a1, long a2, long a3, long a4, long a5, long a6,
++ PyFrameObject *f, int throwflag)
++#elif defined(WITH_DTRACE) && defined(__sparc)
++PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag)
++#else
+ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
++#endif
+ {
+ #ifdef DXPAIRS
+ int lastopcode = 0;
[email protected]@ -915,7 +979,7 @@
+ #ifdef LLTRACE
+ #define FAST_DISPATCH() \
+ { \
+- if (!lltrace && !_Py_TracingPossible) { \
++ if (!lltrace && !_Py_TracingPossible && !PYTHON_LINE_ENABLED()) { \
+ f->f_lasti = INSTR_OFFSET(); \
+ goto *opcode_targets[*next_instr++]; \
+ } \
[email protected]@ -924,7 +988,7 @@
+ #else
+ #define FAST_DISPATCH() \
+ { \
+- if (!_Py_TracingPossible) { \
++ if (!_Py_TracingPossible && !PYTHON_LINE_ENABLED()) { \
+ f->f_lasti = INSTR_OFFSET(); \
+ goto *opcode_targets[*next_instr++]; \
+ } \
[email protected]@ -1160,6 +1224,11 @@
+ }
+ }
+
++#ifdef WITH_DTRACE
++ if (PYTHON_FUNCTION_ENTRY_ENABLED())
++ dtrace_entry(f);
++#endif
++
+ co = f->f_code;
+ names = co->co_names;
+ consts = co->co_consts;
[email protected]@ -1354,6 +1423,12 @@
+ /* Main switch on opcode */
+ READ_TIMESTAMP(inst0);
+
++#ifdef WITH_DTRACE
++ if (PYTHON_LINE_ENABLED()) {
++ maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev);
++ }
++#endif
++
+ switch (opcode) {
+
+ /* BEWARE!
[email protected]@ -3569,6 +3644,10 @@
+
+ /* pop frame */
+ exit_eval_frame:
++#ifdef WITH_DTRACE
++ if (PYTHON_FUNCTION_RETURN_ENABLED())
++ dtrace_return(f);
++#endif
+ Py_LeaveRecursiveCall();
+ f->f_executing = 0;
+ tstate->frame = f->f_back;
[email protected]@ -4319,6 +4398,57 @@
+ return result;
+ }
+
++/*
++ * These shenanigans look like utter madness, but what we're actually doing is
++ * making sure that the ustack helper will see the PyFrameObject pointer on the
++ * stack. We have two tricky cases:
++ *
++ * amd64
++ *
++ * We use up the six registers for passing arguments, meaning the call can't
++ * use a register for passing 'f', and has to push it onto the stack in a known
++ * location.
++ *
++ * And how does "throwflag" figure in to this? -PN
++ *
++ * SPARC
++ *
++ * Here the problem is that (on 32-bit) the compiler is re-using %i0 before
++ * some calls inside PyEval_EvalFrameReal(), which means that when it's saved,
++ * it's just some junk value rather than the real first argument. So, instead,
++ * we trace our proxy PyEval_EvalFrame(), where we 'know' the compiler won't
++ * decide to re-use %i0. We also need to defeat optimization of our proxy.
++ */
++
++#if defined(WITH_DTRACE)
++
++#if defined(__amd64)
++
++PyObject *
++PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
++{
++ volatile PyObject *f2;
++ f2 = PyEval_EvalFrameExReal(0, 0, 0, 0, 0, 0, f, throwflag);
++ return (PyObject *)f2;
++}
++
++#elif defined(__sparc)
++
++volatile int dummy;
++
++PyObject *
++PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
++{
++ volatile PyObject *f2;
++ f2 = PyEval_EvalFrameExReal(f, throwflag);
++ dummy = f->ob_base.ob_base.ob_refcnt;
++ return (PyObject *)f2;
++}
++
++#endif
++#endif
++
++
+ PyObject *
+ _PyEval_CallTracing(PyObject *func, PyObject *args)
+ {
[email protected]@ -4336,6 +4466,51 @@
+ return result;
+ }
+
++#ifdef WITH_DTRACE
++/* See Objects/lnotab_notes.txt for a description of how tracing works. */
++/* Practically a ripoff of "maybe_call_line_trace" function. */
++static void
++maybe_dtrace_line(PyFrameObject *frame,
++ int *instr_lb, int *instr_ub, int *instr_prev)
++{
++ int line = frame->f_lineno;
++ char *co_filename, *co_name;
++
++ /* If the last instruction executed isn't in the current
++ instruction window, reset the window.
++ */
++ if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
++ PyAddrPair bounds;
++ line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
++ &bounds);
++ *instr_lb = bounds.ap_lower;
++ *instr_ub = bounds.ap_upper;
++ }
++ /* If the last instruction falls at the start of a line or if
++ it represents a jump backwards, update the frame's line
++ number and call the trace function. */
++ if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
++ frame->f_lineno = line;
++ co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
++ if (!co_filename)
++ co_filename = "?";
++ co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
++ if (!co_name)
++ co_name = "?";
++ PYTHON_LINE(co_filename, co_name, line);
++ }
++ *instr_prev = frame->f_lasti;
++
++ /*
++ * Currently a USDT tail-call will not receive the correct arguments.
++ * Disable the tail call here.
++ */
++#if defined(__sparc)
++ asm("nop");
++#endif
++}
++#endif
++
+ /* See Objects/lnotab_notes.txt for a description of how tracing works. */
+ static int
+ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
+--- Python-3.5.0a4/configure.~1~ 2015-04-20 00:37:53.000000000 -0700
++++ Python-3.5.0a4/configure 2015-04-20 12:58:28.386851213 -0700
[email protected]@ -642,6 +642,11 @@
+ MACHDEP_OBJS
+ DYNLOADFILE
+ DLINCLDIR
++DTRACEOBJS
++DTRACE_LINKER
++DTRACE_NM
++DFLAGS
++DTRACE
+ THREADOBJ
+ LDLAST
+ USE_THREAD_MODULE
[email protected]@ -818,6 +823,7 @@
+ with_tsc
+ with_pymalloc
+ with_valgrind
++with_dtrace
+ with_fpectl
+ with_libm
+ with_libc
[email protected]@ -1506,6 +1512,7 @@
+ --with(out)-tsc enable/disable timestamp counter profile
+ --with(out)-pymalloc disable/enable specialized mallocs
+ --with-valgrind Enable Valgrind support
++ --with(out)-dtrace disable/enable dtrace support
+ --with-fpectl enable SIGFPE catching
+ --with-libm=STRING math library
+ --with-libc=STRING C library
[email protected]@ -10786,6 +10793,174 @@
+ OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT"
+ fi
+
++# Check for dtrace support
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5
++$as_echo_n "checking for --with-dtrace... " >&6; }
++
++# Check whether --with-dtrace was given.
++if test "${with_dtrace+set}" = set; then :
++ withval=$with_dtrace;
++else
++ with_dtrace=no
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5
++$as_echo "$with_dtrace" >&6; }
++
++
++
++
++
++DTRACE=
++DFLAGS=
++if test "$with_dtrace" = "yes"
++then
++ DTRACE_NM=OTHER
++ DTRACE_LINKER=ld
++ DTRACEOBJS="Python/pydtrace.o"
++ # Extract the first word of "dtrace", so it can be a program name with args.
++set dummy dtrace; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_DTRACE+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $DTRACE in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH$PATH_SEPARATOR/usr/sbin
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ test -z "$ac_cv_path_DTRACE" && ac_cv_path_DTRACE="dtrace"
++ ;;
++esac
++fi
++DTRACE=$ac_cv_path_DTRACE
++if test -n "$DTRACE"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
++$as_echo "$DTRACE" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++ # The cast to long int works around a bug in the HP C Compiler
++# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
++# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
++# This bug is HP SR number 8606223364.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
++$as_echo_n "checking size of long... " >&6; }
++if ${ac_cv_sizeof_long+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
++
++else
++ if test "$ac_cv_type_long" = yes; then
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error 77 "cannot compute sizeof (long)
++See \`config.log' for more details" "$LINENO" 5; }
++ else
++ ac_cv_sizeof_long=0
++ fi
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
++$as_echo "$ac_cv_sizeof_long" >&6; }
++
++
++
++cat >>confdefs.h <<_ACEOF
++#define SIZEOF_LONG $ac_cv_sizeof_long
++_ACEOF
++
++
++ if test "$ac_cv_sizeof_long" -eq 8
++ then
++ DFLAGS="-64"
++ else
++ DFLAGS="-32"
++ fi
++ sys_release="$ac_sys_release"
++ case $ac_sys_system/$sys_release in
++ SunOS/5.10)
++ DTRACE_NM=SOLARIS
++ DTRACE_LINKER=/usr/ccs/bin/ld
++ ;;
++ SunOS/5.11 | SunOS/5.12)
++ DTRACE_NM=SOLARIS
++ DTRACE_LINKER=/usr/bin/ld
++ ;;
++ SunOS/*)
++ DTRACE_LINKER=/usr/ccs/bin/ld
++ ;;
++ Darwin/*)
++ DTRACEOBJS="" # Not needed in Mac
++ # The cast to long int works around a bug in the HP C Compiler
++# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
++# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
++# This bug is HP SR number 8606223364.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
++$as_echo_n "checking size of long... " >&6; }
++if ${ac_cv_sizeof_long+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
++
++else
++ if test "$ac_cv_type_long" = yes; then
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error 77 "cannot compute sizeof (long)
++See \`config.log' for more details" "$LINENO" 5; }
++ else
++ ac_cv_sizeof_long=0
++ fi
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
++$as_echo "$ac_cv_sizeof_long" >&6; }
++
++
++
++cat >>confdefs.h <<_ACEOF
++#define SIZEOF_LONG $ac_cv_sizeof_long
++_ACEOF
++
++
++ if test "$ac_cv_sizeof_long" -eq 8
++ then
++ DFLAGS="-arch i386"
++ else
++ DFLAGS="-arch x86_64"
++ fi
++ ;;
++ esac
++
++$as_echo "#define WITH_DTRACE 1" >>confdefs.h
++
++fi
++
++
++
+ # -I${DLINCLDIR} is added to the compile rule for importdl.o
+
+ DLINCLDIR=.
+--- Python-3.5.0a4/configure.ac.~1~ 2015-04-20 00:37:53.000000000 -0700
++++ Python-3.5.0a4/configure.ac 2015-04-20 12:59:58.383305870 -0700
[email protected]@ -3086,6 +3086,62 @@
+ OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT"
+ fi
+
++# Check for dtrace support
++AC_MSG_CHECKING(for --with-dtrace)
++AC_ARG_WITH(dtrace,
++ AC_HELP_STRING(--with(out)-dtrace, disable/enable dtrace support),,
++ with_dtrace=no)
++AC_MSG_RESULT($with_dtrace)
++
++AC_SUBST(DTRACE)
++AC_SUBST(DFLAGS)
++AC_SUBST(DTRACE_NM)
++AC_SUBST(DTRACE_LINKER)
++DTRACE=
++DFLAGS=
++if test "$with_dtrace" = "yes"
++then
++ DTRACE_NM=OTHER
++ DTRACE_LINKER=ld
++ DTRACEOBJS="Python/pydtrace.o"
++ AC_PATH_PROG(DTRACE, [dtrace], [dtrace], [$PATH$PATH_SEPARATOR/usr/sbin])
++ AC_CHECK_SIZEOF([long])
++ if [test "$ac_cv_sizeof_long" -eq 8]
++ then
++ DFLAGS="-64"
++ else
++ DFLAGS="-32"
++ fi
++ sys_release="$ac_sys_release"
++ case $ac_sys_system/$sys_release in
++ SunOS/5.10)
++ DTRACE_NM=SOLARIS
++ DTRACE_LINKER=/usr/ccs/bin/ld
++ ;;
++ SunOS/5.11 | SunOS/5.12)
++ DTRACE_NM=SOLARIS
++ DTRACE_LINKER=/usr/bin/ld
++ ;;
++ SunOS/*)
++ DTRACE_LINKER=/usr/ccs/bin/ld
++ ;;
++ Darwin/*)
++ DTRACEOBJS="" # Not needed in Mac
++ AC_CHECK_SIZEOF([long])
++ if [test "$ac_cv_sizeof_long" -eq 8]
++ then
++ DFLAGS="-arch i386"
++ else
++ DFLAGS="-arch x86_64"
++ fi
++ ;;
++ esac
++ AC_DEFINE(WITH_DTRACE, 1,
++ [Define if you want to compile in Dtrace support])
++fi
++
++AC_SUBST(DTRACEOBJS)
++
+ # -I${DLINCLDIR} is added to the compile rule for importdl.o
+ AC_SUBST(DLINCLDIR)
+ DLINCLDIR=.
+--- Python-3.5.0a4/pyconfig.h.in.~1~ 2015-04-20 00:37:53.000000000 -0700
++++ Python-3.5.0a4/pyconfig.h.in 2015-04-20 13:00:52.054987861 -0700
[email protected]@ -1355,6 +1355,9 @@
+ /* Define if you want documentation strings in extension modules */
+ #undef WITH_DOC_STRINGS
+
++/* Define if you want to compile in Dtrace support */
++#undef WITH_DTRACE
++
+ /* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
+ Dyld is necessary to support frameworks. */
+--- Python-3.5.0a4/setup.py.~1~ 2015-04-20 00:37:53.000000000 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:01:49.596181289 -0700
[email protected]@ -663,6 +663,9 @@
+ # syslog daemon interface
+ exts.append( Extension('syslog', ['syslogmodule.c']) )
+
++ # jcea DTRACE probes
++ exts.append( Extension('dtrace', ['dtracemodule.c']) )
++
+ #
+ # Here ends the simple stuff. From here on, modules need certain
+ # libraries, are platform-specific, or present other surprises.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/01-bits.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,28 @@
+#
+# This patch addresses problems with the configure script.
+# As it is Solaris-specific, it is not suitable for upstream.
+#
+--- Python-3.5.0a4/configure.ac.~2~ 2015-04-20 13:02:40.184381369 -0700
++++ Python-3.5.0a4/configure.ac 2015-04-20 13:02:40.208203720 -0700
[email protected]@ -5,7 +5,7 @@
+ # Set VERSION so we only need to edit in one place (i.e., here)
+ m4_define(PYTHON_VERSION, 3.5)
+
+-AC_PREREQ(2.65)
++AC_PREREQ(2.68)
+
+ AC_INIT(python, PYTHON_VERSION, http://bugs.python.org/)
+
[email protected]@ -2302,12 +2302,6 @@
+ if test -z "$CCSHARED"
+ then
+ case $ac_sys_system/$ac_sys_release in
+- SunOS*) if test "$GCC" = yes;
+- then CCSHARED="-fPIC";
+- elif test `uname -p` = sparc;
+- then CCSHARED="-xcode=pic32";
+- else CCSHARED="-Kpic";
+- fi;;
+ hp*|HP*) if test "$GCC" = yes;
+ then CCSHARED="-fPIC";
+ else CCSHARED="+z";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/03-setup.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,92 @@
+This patch modifies the setup script to support Solaris.
+As it is Solaris-specific, it is not suitable for upstream.
+
+--- Python-3.5.0a4/setup.py.~2~ 2015-04-20 13:10:20.522357068 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:10:20.553743713 -0700
[email protected]@ -465,12 +465,15 @@
+ os.unlink(tmpfile)
+
+ def detect_modules(self):
+- # Ensure that /usr/local is always used, but the local build
+- # directories (i.e. '.' and 'Include') must be first. See issue
+- # 10520.
+ if not cross_compiling:
+- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
+- add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
++ if host_platform != 'sunos5':
++ # Upstream notes the following for source builds:
++ # Ensure that /usr/local is always used, but the local build
++ # directories (i.e. '.' and 'Include') must be first. See
++ # issue 10520.
++ # But we skip that for Solaris system builds.
++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
++ add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
+ # only change this for cross builds for 3.3, issues on Mageia
+ if cross_compiling:
+ self.add_gcc_paths()
[email protected]@ -756,6 +759,13 @@
+ ['/usr/lib/termcap'],
+ 'termcap'):
+ readline_libs.append('termcap')
++
++ if host_platform == 'sunos5':
++ # insert '-zrecord' before the readline libraries that we
++ # want to link with to avoid rl_insert() elimination
++ readline_extra_link_args = ('-Wl,-zrecord','-lreadline','-lncurses')
++ readline_libs = ()
++
+ exts.append( Extension('readline', ['readline.c'],
+ library_dirs=['/usr/lib/termcap'],
+ extra_link_args=readline_extra_link_args,
[email protected]@ -1315,6 +1325,8 @@
+ curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1'))
+
+ if curses_library.startswith('ncurses'):
++ if host_platform == 'sunos5':
++ curses_includes.append('/usr/include/ncurses')
+ curses_libs = [curses_library]
+ exts.append( Extension('_curses', ['_cursesmodule.c'],
+ include_dirs=curses_includes,
[email protected]@ -1339,10 +1351,32 @@
+ # If the curses module is enabled, check for the panel module
+ if (module_enabled(exts, '_curses') and
+ self.compiler.find_library_file(lib_dirs, panel_library)):
++ panel_lib_dirs = []
++ if host_platform == 'sunos5':
++ # Look for libpanel under /usr/gnu/lib on Solaris.
++ # os.uname() does not include the processor. platform.uname()
++ # does, but the platform module is not available in setup.
++ # Work around this by parsing os.system('uname -p') output.
++ tmpfile = os.path.join(self.build_temp, 'processor')
++ if not os.path.exists(self.build_temp):
++ os.makedirs(self.build_temp)
++ os.system('/usr/bin/uname -p > %s 2> /dev/null' %tmpfile)
++ processor = ''
++ try:
++ with open(tmpfile) as fp:
++ processor = fp.readline().strip()
++ finally:
++ os.unlink(tmpfile)
++ if processor == 'sparc':
++ panel_lib_dirs.append('/usr/gnu/lib/sparcv9')
++ else:
++ panel_lib_dirs.append('/usr/gnu/lib/amd64')
+ exts.append( Extension('_curses_panel', ['_curses_panel.c'],
+ include_dirs=curses_includes,
+ define_macros=curses_defines,
+- libraries = [panel_library] + curses_libs) )
++ libraries = [panel_library] + curses_libs,
++ library_dirs = panel_lib_dirs,
++ runtime_library_dirs = panel_lib_dirs) )
+ else:
+ missing.append('_curses_panel')
+
[email protected]@ -1938,7 +1972,7 @@
+ # this option. If you want to compile ctypes with the Sun
+ # compiler, please research a proper solution, instead of
+ # finding some -z option for the Sun compiler.
+- extra_link_args.append('-mimpure-text')
++ pass
+
+ elif host_platform.startswith('hp-ux'):
+ extra_link_args.append('-fPIC')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/04-vendor-packages.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,8 @@
+This patch makes Python support the vendor-packages directory.
+As it is Solaris-specific, it is not suitable for upstream.
+
+--- /dev/null Sat Feb 12 00:21:26 2011
++++ Python-3.4.0/Lib/site-packages/vendor-packages.pth Sat Feb 12 00:47:05 2011
[email protected]@ -0,0 +1,1 @@
++import site; site.addsitedir('/usr/lib/python3.5/vendor-packages')
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/05-studio-profile.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,77 @@
+This changes Python's standard profile-guided build target to work with
+Studio instead of gcc. The unfortunate repetition of options seen below
+is a workaround for build peculiarities and to meet Studio's requirement
+that the profiling options be used at all steps of the build -- not just
+compilation. As it is Solaris-specific, it is not suitable for upstream.
+
+--- Python-3.5.0rc2/Makefile.pre.in.~2~ 2015-09-02 11:35:43.321886346 -0700
++++ Python-3.5.0rc2/Makefile.pre.in 2015-09-02 11:35:43.430843102 -0700
[email protected]@ -488,30 +488,39 @@
+ profile-opt:
+ @echo "Building with support for profile generation:"
+ $(MAKE) clean
++ $(MAKE) profile-removal
+ $(MAKE) build_all_generate_profile
+ @echo "Running benchmark to generate profile data:"
+- $(MAKE) profile-removal
+ $(MAKE) run_profile_task
+ @echo "Rebuilding with profile guided optimizations:"
+ $(MAKE) clean
+ $(MAKE) build_all_use_profile
+
+ build_all_generate_profile:
+- $(MAKE) all CFLAGS_NODIST="$(CFLAGS) -fprofile-generate" LDFLAGS="-fprofile-generate" LIBS="$(LIBS) -lgcov"
++ $(MAKE) all CC="$(CC) -xprofile=collect:$(XPROFILE_DIR)" \
++ CFLAGS_NODIST="$(CFLAGS) -xprofile=collect:$(XPROFILE_DIR)" \
++ LDFLAGS="$(LDFLAGS) -xprofile=collect:$(XPROFILE_DIR)" \
++ BLDSHARED="$(BLDSHARED) -xprofile=collect:$(XPROFILE_DIR)"
+
+ run_profile_task:
+ : # FIXME: can't run for a cross build
+- $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK)
++ LD_LIBRARY_PATH=. $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK)
+
+ build_all_use_profile:
+- $(MAKE) all CFLAGS_NODIST="$(CFLAGS) -fprofile-use -fprofile-correction"
++ $(MAKE) all CC="$(CC) -xprofile=use:$(XPROFILE_DIR)" \
++ CFLAGS_NODIST="$(CFLAGS) -xprofile=use:$(XPROFILE_DIR)" \
++ LDFLAGS="$(LDFLAGS) -xprofile=use:$(XPROFILE_DIR)" \
++ BLDSHARED="$(BLDSHARED) -xprofile=use:$(XPROFILE_DIR)"
+
+ # Compile and run with gcov
+ .PHONY=coverage coverage-lcov coverage-report
+ coverage:
+ @echo "Building with support for coverage checking:"
+ $(MAKE) clean profile-removal
+- $(MAKE) all CFLAGS="$(CFLAGS) -O0 -pg -fprofile-arcs -ftest-coverage" LIBS="$(LIBS) -lgcov"
++ $(MAKE) all CC="$(CC) -xprofile=tcov" \
++ CFLAGS="$(CFLAGS) -xO1 -xprofile=tcov" \
++ LDFLAGS="$(LDFLAGS) -xprofile=tcov" \
++ BLDSHARED="$(BLDSHARED) -xprofile=tcov"
+
+ coverage-lcov:
+ @echo "Creating Coverage HTML report with LCOV:"
[email protected]@ -583,13 +592,9 @@
+ # -s, --silent or --quiet is always the first char.
+ # Under BSD make, MAKEFLAGS might be " -s -v x=y".
+ sharedmods: $(BUILDPYTHON) pybuilddir.txt
+- @case "$$MAKEFLAGS" in \
+- *\ -s*|s*) quiet="-q";; \
+- *) quiet="";; \
+- esac; \
+ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
+ _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \
+- $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
++ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py build
+
+ # Build static library
+ # avoid long command lines, same as LIBRARY_OBJS
[email protected]@ -1627,7 +1632,7 @@
+ -rm -f Programs/_testembed Programs/_freeze_importlib
+
+ profile-removal:
+- find . -name '*.gc??' -exec rm -f {} ';'
++ find . -name '*profile' -exec rm -f {} ';'
+ rm -f $(COVERAGE_INFO)
+ rm -rf $(COVERAGE_REPORT)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/06-test_distutils.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,32 @@
+This patch is the sole remainder of the 3.4 patch for 64-bit modules.
+As the patch is Solaris-specific, it is not suitable for upstream.
+
+--- Python-3.4.2/Lib/distutils/tests/test_sysconfig.py.~1~ 2014-09-22 05:56:59.000000000 -0700
++++ Python-3.4.2/Lib/distutils/tests/test_sysconfig.py 2014-09-22 14:10:18.427824361 -0700
[email protected]@ -1,4 +1,5 @@
+ """Tests for distutils.sysconfig."""
++import sys
+ import os
+ import shutil
+ import subprocess
[email protected]@ -127,6 +128,8 @@
+
+ def test_sysconfig_module(self):
+ import sysconfig as global_sysconfig
++ if sys.platform == 'sunos5':
++ return
+ self.assertEqual(global_sysconfig.get_config_var('CFLAGS'),
+ sysconfig.get_config_var('CFLAGS'))
+ self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'),
[email protected]@ -152,8 +155,9 @@
+ import sysconfig as global_sysconfig
+ if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'):
+ self.skipTest('compiler flags customized')
+- self.assertEqual(global_sysconfig.get_config_var('LDSHARED'),
+- sysconfig.get_config_var('LDSHARED'))
++ if sys.platform != 'sunos5':
++ self.assertEqual(global_sysconfig.get_config_var('LDSHARED'),
++ sysconfig.get_config_var('LDSHARED'))
+ self.assertEqual(global_sysconfig.get_config_var('CC'),
+ sysconfig.get_config_var('CC'))
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/07-ucred.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,476 @@
+This patch provides Python ucred support. It may be contributed upstream at
+some point, but the suitability (or lack thereof) has not yet been determined.
+
+diff --git Python-2.6.4/Modules/ucred.c Python-2.6.4/Modules/ucred.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/ucred.c
[email protected]@ -0,0 +1,404 @@
++/*
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ *
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++#include <Python.h>
++
++#include <stdio.h>
++#include <priv.h>
++#include <ucred.h>
++#include <ctype.h>
++#include <tsol/label.h>
++
++typedef struct {
++ PyObject_HEAD
++ ucred_t *ucred;
++} pyucred_t;
++
++#define pyucred_getlongid(name, type) \
++ static PyObject * \
++ pyucred_get##name(pyucred_t *uc) \
++ { \
++ type val; \
++ \
++ if (uc->ucred == NULL) { \
++ errno = EINVAL; \
++ PyErr_SetFromErrno(PyExc_OSError); \
++ return (NULL); \
++ } \
++ \
++ if ((val = ucred_get##name(uc->ucred)) == -1) { \
++ PyErr_SetFromErrno(PyExc_OSError); \
++ return (NULL); \
++ } \
++ \
++ return (Py_BuildValue("l", (long)val)); \
++ }
++
++pyucred_getlongid(euid, uid_t)
++pyucred_getlongid(ruid, uid_t)
++pyucred_getlongid(suid, uid_t)
++pyucred_getlongid(egid, gid_t)
++pyucred_getlongid(rgid, gid_t)
++pyucred_getlongid(sgid, gid_t)
++pyucred_getlongid(pid, pid_t)
++pyucred_getlongid(projid, projid_t)
++pyucred_getlongid(zoneid, zoneid_t)
++
++static PyObject *
++pyucred_getgroups(pyucred_t *uc)
++{
++ const gid_t *groups;
++ PyObject *list;
++ int len;
++ int i;
++
++ if (uc->ucred == NULL) {
++ errno = EINVAL;
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ if ((len = ucred_getgroups(uc->ucred, &groups)) == -1) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ if ((list = PyList_New(len)) == NULL)
++ return (NULL);
++
++ for (i = 0; i < len; i++) {
++ PyObject *gid = Py_BuildValue("l", (long)groups[i]);
++ if (PyList_SetItem(list, i, gid) == -1)
++ return (NULL);
++ }
++
++ return (list);
++}
++
++static PyObject *
++pyucred_getlabel(pyucred_t *uc)
++{
++ m_label_t *label;
++ PyObject *ret;
++ char *str;
++
++ if (uc->ucred == NULL) {
++ errno = EINVAL;
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ label = ucred_getlabel(uc->ucred);
++ if (label == NULL)
++ return (Py_BuildValue("s", ""));
++
++ if (label_to_str(label, &str, M_LABEL, DEF_NAMES) == -1) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ ret = Py_BuildValue("s", str);
++ free(str);
++ return (ret);
++}
++
++static PyObject *
++pyucred_getpflags(pyucred_t *uc, PyObject *args, PyObject *kwargs)
++{
++ static char *kwlist[] = { "flags", NULL };
++ uint_t flags;
++
++ if (uc->ucred == NULL) {
++ errno = EINVAL;
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
++ &flags))
++ return (NULL);
++
++ if ((flags = ucred_getpflags(uc->ucred, flags)) == (uint_t)-1) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("i", flags));
++}
++
++static PyObject *
++pyucred_has_priv(pyucred_t *uc, PyObject *args, PyObject *kwargs)
++{
++ static char *kwlist[] = { "set", "priv", NULL };
++ const priv_set_t *privs;
++ const char *set;
++ const char *priv;
++
++ if (uc->ucred == NULL) {
++ errno = EINVAL;
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist,
++ &set, &priv))
++ return (NULL);
++
++ if ((privs = ucred_getprivset(uc->ucred, set)) == NULL) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ if (priv_ismember(privs, priv)) {
++ Py_INCREF(Py_True);
++ return Py_True;
++ }
++
++ Py_INCREF(Py_False);
++ return Py_False;
++}
++
++PyDoc_STRVAR(pyucred_getlabel_doc,
++ "getlabel() -> string\n"
++ "\n"
++ "Return the Trusted Extensions label string, or an "
++ "empty string if not available. The label string is "
++ "converted using the default name and M_LABEL (human-readable). "
++ "Raises OSError. See label_to_str(3TSOL).");
++PyDoc_STRVAR(pyucred_getpflags_doc,
++ "getpflags(flags) -> int\n"
++ "\n"
++ "Return the values of the specified privilege flags.");
++PyDoc_STRVAR(pyucred_has_priv_doc,
++ "has_priv(set, priv) -> bool\n"
++ "\n"
++ "Return true if the given privilege is set in the "
++ "specified set. Raises OSError if the set or privilege is "
++ "invalid, or a problem occurs.\n"
++ "\n"
++ "Currently, the following privilege sets are defined, as "
++ "described in privileges(5):\n"
++ "\n"
++ "Effective\n"
++ "Permitted\n"
++ "Inheritable\n"
++ "Limit\n");
++
++static PyMethodDef pyucred_methods[] = {
++ { "geteuid", (PyCFunction)pyucred_geteuid, METH_NOARGS,
++ "Return the effective user ID." },
++ { "getruid", (PyCFunction)pyucred_getruid, METH_NOARGS,
++ "Return the real user ID." },
++ { "getsuid", (PyCFunction)pyucred_getsuid, METH_NOARGS,
++ "Return the saved user ID." },
++ { "getegid", (PyCFunction)pyucred_getegid, METH_NOARGS,
++ "Return the effective group ID." },
++ { "getrgid", (PyCFunction)pyucred_getrgid, METH_NOARGS,
++ "Return the real group ID." },
++ { "getsgid", (PyCFunction)pyucred_getsgid, METH_NOARGS,
++ "Return the saved group ID." },
++ { "getpid", (PyCFunction)pyucred_getpid, METH_NOARGS,
++ "Return the effective user ID." },
++ { "getprojid", (PyCFunction)pyucred_getprojid, METH_NOARGS,
++ "Return the project ID." },
++ { "getzoneid", (PyCFunction)pyucred_getzoneid, METH_NOARGS,
++ "Return the zone ID." },
++ { "getgroups", (PyCFunction)pyucred_getgroups, METH_NOARGS,
++ "Return a list of group IDs." },
++ { "getlabel", (PyCFunction)pyucred_getlabel, METH_NOARGS,
++ pyucred_getlabel_doc },
++ { "getpflags", (PyCFunction)pyucred_getpflags,
++ METH_VARARGS|METH_KEYWORDS, pyucred_getpflags_doc },
++ { "has_priv", (PyCFunction)pyucred_has_priv,
++ METH_VARARGS|METH_KEYWORDS, pyucred_has_priv_doc },
++ { NULL, NULL }
++};
++
++static int
++pyucred_init(PyObject *self, PyObject *args, PyObject *kwargs)
++{
++ pyucred_t *uc = (pyucred_t *)self;
++ uc->ucred = NULL;
++ return (0);
++}
++
++static void
++pyucred_dealloc(PyObject *self)
++{
++ pyucred_t *uc = (pyucred_t *)self;
++ if (uc->ucred != NULL)
++ ucred_free(uc->ucred);
++ Py_TYPE(self)->tp_free(self);
++}
++
++static PyTypeObject pyucred_type = {
++ PyVarObject_HEAD_INIT(NULL, 0)
++ "ucred.ucred", /*tp_name*/
++ sizeof (pyucred_t), /*tp_basicsize*/
++ 0, /*tp_itemsize*/
++ pyucred_dealloc, /*tp_dealloc*/
++ 0, /*tp_print*/
++ 0, /*tp_getattr*/
++ 0, /*tp_setattr*/
++ 0, /*tp_reserved*/
++ 0, /*tp_repr*/
++ 0, /*tp_as_number*/
++ 0, /*tp_as_sequence*/
++ 0, /*tp_as_mapping*/
++ 0, /*tp_hash */
++ 0, /*tp_call*/
++ 0, /*tp_str*/
++ 0, /*tp_getattro*/
++ 0, /*tp_setattro*/
++ 0, /*tp_as_buffer*/
++ Py_TPFLAGS_DEFAULT, /*tp_flags*/
++ "user credentials", /*tp_doc */
++ 0, /* tp_traverse */
++ 0, /* tp_clear */
++ 0, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ 0, /* tp_iter */
++ 0, /* tp_iternext */
++ pyucred_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ (initproc)pyucred_init, /* tp_init */
++ 0, /* tp_alloc */
++ 0, /* tp_new */
++ 0, /* tp_free */
++ 0, /* tp_is_gc */
++};
++
++static PyObject *
++pyucred_new(const ucred_t *uc)
++{
++ pyucred_t *self;
++
++ self = (pyucred_t *)PyObject_CallObject((PyObject *)&pyucred_type, NULL);
++
++ if (self == NULL)
++ return (NULL);
++
++ self->ucred = (ucred_t *)uc;
++
++ return ((PyObject *)self);
++}
++
++static PyObject *
++pyucred_get(PyObject *o, PyObject *args, PyObject *kwargs)
++{
++ static char *kwlist[] = { "pid", NULL };
++ ucred_t *ucred = NULL;
++ int pid;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
++ &pid))
++ return (NULL);
++
++ ucred = ucred_get(pid);
++
++ if (ucred == NULL) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ return (pyucred_new(ucred));
++}
++
++static PyObject *
++pyucred_getpeer(PyObject *o, PyObject *args, PyObject *kwargs)
++{
++ static char *kwlist[] = { "fd", NULL };
++ ucred_t *ucred = NULL;
++ int fd;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist,
++ &fd))
++ return (NULL);
++
++ if (getpeerucred(fd, &ucred) == -1) {
++ PyErr_SetFromErrno(PyExc_OSError);
++ return (NULL);
++ }
++
++ return (pyucred_new(ucred));
++}
++
++PyDoc_STRVAR(pyucred_get_doc,
++ "get(pid) -> ucred\n"
++ "\n"
++ "Return the credentials of the specified process ID. "
++ "Raises OSError. See ucred_get(3C).");
++PyDoc_STRVAR(pyucred_getpeer_doc,
++ "getpeer(fd) -> ucred\n"
++ "\n"
++ "Return the credentials of the peer endpoint of a "
++ "connection-oriented socket (SOCK_STREAM) or STREAM fd "
++ "at the time the endpoint was created or the connection "
++ "was established. Raises OSError. See getpeerucred(3C).");
++
++static struct PyMethodDef pyucred_module_methods[] = {
++ { "get", (PyCFunction) pyucred_get,
++ METH_VARARGS|METH_KEYWORDS, pyucred_get_doc },
++ { "getpeer", (PyCFunction) pyucred_getpeer,
++ METH_VARARGS|METH_KEYWORDS, pyucred_getpeer_doc },
++ { NULL, NULL, 0, NULL }
++};
++
++PyDoc_STRVAR(pyucred_module_doc,
++ "This module provides an interface to the user credential access "
++ "methods, obtainable either by process ID or file descriptor.");
++
++PyMODINIT_FUNC
++PyInit_ucred (void)
++{
++ PyObject *m;
++
++ static struct PyModuleDef moduledef = {
++ PyModuleDef_HEAD_INIT,
++ "ucred",
++ pyucred_module_doc,
++ -1,
++ pyucred_module_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ };
++
++ m = PyModule_Create(&moduledef);
++
++ pyucred_type.tp_new = PyType_GenericNew;
++ if (PyType_Ready(&pyucred_type) < 0)
++ return NULL;
++
++ Py_INCREF(&pyucred_type);
++
++ PyModule_AddObject(m, "ucred", (PyObject *)&pyucred_type);
++
++ return m;
++}
+--- Python-3.5.0a4/setup.py.~3~ 2015-04-20 13:25:43.044301257 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:25:43.100051905 -0700
[email protected]@ -1532,6 +1532,13 @@
+ # Stefan Krah's _decimal module
+ exts.append(self._decimal_ext())
+
++ # ucred module (Solaris)
++ ucred_inc = find_file('ucred.h', [], inc_dirs)
++ tsol_inc = find_file('tsol/label.h', [], inc_dirs)
++ if ucred_inc is not None and tsol_inc is not None:
++ exts.append( Extension('ucred', ['ucred.c'],
++ libraries = ['tsol']) )
++
+ # Thomas Heller's _ctypes module
+ self.detect_ctypes(inc_dirs, lib_dirs)
+
+--- /dev/null 2011-02-12 03:14:16.000000000 -0600
++++ Python-2.6.4/Lib/test/ucredtest.py 2011-01-20 13:52:42.945657919 -0600
[email protected]@ -0,0 +1,45 @@
++#!/usr/bin/python3.5
++
++import ucred
++import os
++
++uc = ucred.get(os.getpid())
++
++print("pid = %d" % uc.getpid())
++print("euid = %d" % uc.geteuid())
++print("ruid = %d" % uc.getruid())
++print("suid = %d" % uc.getsuid())
++print("egid = %d" % uc.getegid())
++print("rgid = %d" % uc.getrgid())
++print("sgid = %d" % uc.getsgid())
++print("zoneid = %d" % uc.getzoneid())
++print("projid = %d" % uc.getprojid())
++print("groups = %s" % uc.getgroups())
++print("label = %s" % uc.getlabel())
++
++print("getpflags(0x1) = %d" % uc.getpflags(0x1))
++print("getpflags(0x2) = %d" % uc.getpflags(0x2))
++print("has_priv(Effective, proc_fork) = %d" % uc.has_priv("Effective", "proc_fork"))
++print("has_priv(Permitted, proc_fork) = %d" % uc.has_priv("Permitted", "proc_fork"))
++print("has_priv(Inheritable, proc_fork) = %d" % uc.has_priv("Inheritable", "proc_fork"))
++print("has_priv(Limit, file_setid) = %d" % uc.has_priv("Limit", "file_setid"))
++print("has_priv(Effective, file_setid) = %d" % uc.has_priv("Effective", "file_setid"))
++try:
++ uc.has_priv("Effective", "proc_bork")
++except OSError as e:
++ print(e)
++try:
++ uc.has_priv("Defective", "proc_fork")
++except OSError as e:
++ print(e)
++try:
++ uc.has_priv("Defective", "proc_bork")
++except OSError as e:
++ print(e)
++
++del uc
++uc = ucred.ucred()
++try:
++ uc.getpid()
++except OSError as e:
++ print(e)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/08-dlpi.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,1339 @@
+This patch provides Python dlpi support. It may be contributed upstream at
+some point, but the suitability (or lack thereof) has not yet been determined.
+
+--- /dev/null
++++ Python-3.4.0/Modules/dlpimodule.c
[email protected]@ -0,0 +1,1219 @@
++/*
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ *
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++#include <Python.h>
++#include <stdio.h>
++#include <libdlpi.h>
++
++typedef struct {
++ PyObject_HEAD
++ dlpi_handle_t dlpihdl;
++} pylink_t;
++
++typedef struct {
++ PyObject *pyfunc;
++ PyObject *pyarg;
++} callback_data_t;
++
++/*
++ * dlpi_err: the only exception raised for libdlpi related error.
++ * The accompanying value is:
++ * (dlpi_error_number, string), when it's a dlpi specific error,
++ * or, (DL_SYSERR, errno, string), when it's coming from a system call.
++ */
++static PyObject *dlpi_err;
++
++static void
++dlpi_raise_exception(int err)
++{
++ PyObject *e = NULL;
++
++ if (err == DL_SYSERR) {
++ e = Py_BuildValue("(iis)", DL_SYSERR, errno, strerror(errno));
++ } else {
++ e = Py_BuildValue("(is)", err, dlpi_strerror(err));
++ }
++ if (e != NULL) {
++ PyErr_SetObject(dlpi_err, e);
++ Py_DECREF(e);
++ }
++}
++
++PyDoc_STRVAR(link_doc,
++ "link(linkname[, flags]) -> link object\n"
++ "\n"
++ "Open linkname with specified flags.\n"
++ "Three flags are supported: PASSIVE, RAW, NATIVE.\n"
++ "And these flags can be bitwise-OR'ed together(default flag is 0).\n"
++ "You need sys_net_rawaccess privilege to open a link.\n"
++ "See dlpi_open(3DLPI).\n"
++);
++static int
++link_init(PyObject *self, PyObject *args, PyObject *kwds)
++{
++ uint_t flags = 0;
++ dlpi_handle_t dh;
++ char *linkname;
++ int rval;
++ static char *keywords[] = {"linkname", "flags", NULL};
++ pylink_t *link = (pylink_t *)self;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|I", keywords,
++ &linkname, &flags))
++ return (-1);
++
++ if ((rval = dlpi_open(linkname, &dh, flags)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (-1);
++ }
++
++ link->dlpihdl = dh;
++
++ return (0);
++}
++
++static void
++link_dealloc(pylink_t *link)
++{
++ if (link->dlpihdl != NULL)
++ dlpi_close(link->dlpihdl);
++ Py_TYPE(link)->tp_free((PyObject *)link);
++}
++
++PyDoc_STRVAR(bind_doc,
++ "bind(sap) -> unsigned int\n"
++ "\n"
++ "Attempts to bind the link to specified SAP, or ANY_SAP.\n"
++ "Returns the SAP that the function actually bound to, which\n"
++ "could be different from the SAP requested.\n"
++ "See dlpi_bind(3DLPI).\n"
++);
++static PyObject *
++link_bind(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ uint_t sap = 0, boundsap = 0;
++ static char *keywords[] = {"sap", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", keywords, &sap))
++ return (NULL);
++
++ if ((rval = dlpi_bind(link->dlpihdl, sap, &boundsap)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I", boundsap));
++}
++
++PyDoc_STRVAR(unbind_doc,
++ "unbind() -> None\n"
++ "\n"
++ "Attempts to unbind the link from previously bound sap.\n"
++ "See dlpi_unbind(3DLPI).\n"
++);
++static PyObject *
++link_unbind(pylink_t *link)
++{
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_unbind(link->dlpihdl)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(send_doc,
++ "send(destaddr, message[, sap, minpri, maxpri]) -> None\n"
++ "\n"
++ "Attempts to send message over this link to sap on destaddr.\n"
++ "If SAP is not specified, the bound SAP is used\n"
++ "You can also specify priority range (minpri, maxpri).\n"
++ "See dlpi_send(3DLPI).\n"
++);
++static PyObject *
++link_send(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ char *daddr = NULL, *msgbuf = NULL;
++ size_t daddrlen = 0, msglen = 0;
++ t_scalar_t minpri = DL_QOS_DONT_CARE, maxpri = DL_QOS_DONT_CARE;
++ uint_t sap = DLPI_ANY_SAP;
++ dlpi_sendinfo_t ds, *dsp = NULL;
++ static char *keywords[] =
++ {"destaddr", "message", "sap", "minpri", "maxpri", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#s#|Iii", keywords,
++ &daddr, &daddrlen, &msgbuf, &msglen, &sap, &minpri, &maxpri))
++ return (NULL);
++
++ if ((sap != DLPI_ANY_SAP) || (minpri != DL_QOS_DONT_CARE) ||
++ (maxpri != DL_QOS_DONT_CARE)) {
++ ds.dsi_sap = sap;
++ ds.dsi_prio.dl_min = minpri;
++ ds.dsi_prio.dl_max = maxpri;
++ dsp = &ds;
++ }
++
++ if ((rval = dlpi_send(link->dlpihdl, daddr, daddrlen,
++ msgbuf, msglen, dsp)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(recv_doc,
++ "recv(msglen[, timeout]) -> (string, string), or (None, None)\n"
++ "\n"
++ "Attempts to receive message over this link.\n"
++ "You need to specify the message length for the received message.\n"
++ "And you can specify timeout value in milliseconds.\n"
++ "The default timeout value is -1 (wait forever).\n"
++ "Returns (source address, message data), or (None, None) when error occurs.\n"
++ "See dlpi_recv(3DLPI).\n"
++);
++static PyObject *
++link_recv(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ PyObject *obj;
++ char *saddr = NULL, *msgbuf = NULL;
++ size_t saddrlen = 0, msglen = 0, *saddrlenp = NULL, *msglenp = NULL;
++ int msec = -1; /* block until receive data */
++ static char *keywords[] = {"msglen", "timeout", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|i",
++ keywords, &msglen, &msec))
++ return (NULL);
++
++ if (msglen > 0) {
++ msgbuf = malloc(msglen);
++ if (msgbuf == NULL) {
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++ saddrlen = DLPI_PHYSADDR_MAX;
++ saddr = malloc(saddrlen);
++ if (saddr == NULL) {
++ dlpi_raise_exception(DL_SYSERR);
++ free(msgbuf);
++ return (NULL);
++ }
++ msglenp = &msglen;
++ saddrlenp = &saddrlen;
++ }
++
++ if ((rval = dlpi_recv(link->dlpihdl, saddr, saddrlenp, msgbuf,
++ msglenp, msec, NULL)) != DLPI_SUCCESS) {
++ if (msgbuf != NULL)
++ free(msgbuf);
++ if (saddr != NULL)
++ free(saddr);
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ obj = Py_BuildValue("s#s#", saddr, saddrlen, msgbuf, msglen);
++ if (msgbuf != NULL)
++ free(msgbuf);
++ if (saddr != NULL)
++ free(saddr);
++ return (obj);
++}
++
++PyDoc_STRVAR(disabmulti_doc,
++ "disabmulti(address) -> None\n"
++ "\n"
++ "Disable a specified multicast address on this link.\n"
++ "See dlpi_disabmulti(3DLPI).\n"
++);
++static PyObject *
++link_disabmulti(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ char *addr = NULL;
++ size_t addrlen = 0;
++ static char *keywords[] = {"address", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", keywords,
++ &addr, &addrlen))
++ return (NULL);
++
++ if ((addrlen == 0) || (addrlen > DLPI_PHYSADDR_MAX)) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_disabmulti(link->dlpihdl, addr, addrlen)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(enabmulti_doc,
++ "enabmulti(address) -> None\n"
++ "\n"
++ "Enable a specified multicast address on this link.\n"
++ "See dlpi_enabmulti(3DLPI).\n"
++);
++static PyObject *
++link_enabmulti(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ char *addr = NULL;
++ size_t addrlen = 0;
++ static char *keywords[] = {"address", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", keywords,
++ &addr, &addrlen))
++ return (NULL);
++
++ if ((addrlen == 0) || (addrlen > DLPI_PHYSADDR_MAX)) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_enabmulti(link->dlpihdl, addr, addrlen)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++static void
++dlpi_callback(dlpi_handle_t hdl, dlpi_notifyinfo_t *ni, void *arg)
++{
++ callback_data_t *cd = (callback_data_t *)arg;
++ PyObject *arglist, *result;
++
++ switch (ni->dni_note) {
++ case DL_NOTE_SPEED:
++ arglist = Py_BuildValue("(OII)",
++ cd->pyarg, ni->dni_note, ni->dni_speed);
++ break;
++ case DL_NOTE_SDU_SIZE:
++ arglist = Py_BuildValue("(OII)",
++ cd->pyarg, ni->dni_note, ni->dni_size);
++ break;
++ case DL_NOTE_PHYS_ADDR:
++ arglist = Py_BuildValue("(OIs#)",
++ cd->pyarg, ni->dni_note, ni->dni_physaddr,
++ ni->dni_physaddrlen);
++ break;
++ default:
++ arglist = Py_BuildValue("(OIO)", cd->pyarg, ni->dni_note,
++ Py_None);
++ }
++
++ result = PyEval_CallObject(cd->pyfunc, arglist);
++ Py_DECREF(arglist);
++ if (result == NULL) {
++ PyErr_Clear(); /* cannot raise error */
++ }
++ Py_DECREF(result);
++ Py_DECREF(cd->pyfunc);
++ Py_XDECREF(cd->pyarg);
++ free(cd);
++}
++
++PyDoc_STRVAR(enabnotify_doc,
++ "enabnotify(events, function[, arg]) -> unsigned long\n"
++ "\n"
++ "Enables a notification callback for the set of specified events,\n"
++ "which must be one or more (by a logical OR) events listed as below:\n"
++ "NOTE_LINK_DOWN Notify when link has gone down\n"
++ "NOTE_LINK_UP Notify when link has come up\n"
++ "NOTE_PHYS_ADDR Notify when address changes\n"
++ "NOTE_SDU_SIZE Notify when MTU changes\n"
++ "NOTE_SPEED Notify when speed changes\n"
++ "NOTE_PROMISC_ON_PHYS Notify when PROMISC_PHYS is set\n"
++ "NOTE_PROMISC_OFF_PHYS Notify when PROMISC_PHYS is cleared\n"
++ "Returns a handle for this registration.\n"
++ "See dlpi_enabnotify(3DLPI).\n"
++);
++static PyObject *
++link_enabnotify(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ PyObject *func = NULL, *arg = NULL;
++ callback_data_t *cd;
++ uint_t notes = 0;
++ static char *keywords[] = {"events", "function", "arg", NULL};
++ dlpi_notifyid_t id;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "IO|O",
++ keywords, ¬es, &func, &arg))
++ return (NULL);
++
++ if (!PyCallable_Check(func)) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ cd = malloc(sizeof(callback_data_t));
++ if (cd == NULL) {
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++ Py_INCREF(func);
++ Py_XINCREF(arg);
++ cd->pyfunc = func;
++ cd->pyarg = arg;
++
++ if ((rval = dlpi_enabnotify(link->dlpihdl, notes, dlpi_callback,
++ cd, &id)) != DLPI_SUCCESS) {
++ free(cd);
++ Py_DECREF(func);
++ Py_XDECREF(arg);
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("k", id));
++}
++
++PyDoc_STRVAR(disabnotify_doc,
++ "disabnotify(handle) -> argument object, or None\n"
++ "\n"
++ "Disables the notification registration associated with handle.\n"
++ "You should get this handle by calling enabnotify().\n"
++ "Returns the argument passed in when registering the callback, or None.\n"
++ "See dlpi_disabnotify(3DLPI).\n"
++);
++static PyObject *
++link_disabnotify(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ dlpi_notifyid_t id;
++ callback_data_t *arg;
++ PyObject *pyargsaved;
++ static char *keywords[] = {"handle", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "k", keywords, &id))
++ return (NULL);
++
++ if ((rval = dlpi_disabnotify(link->dlpihdl, id, (void **)&arg)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ /* clean up */
++ pyargsaved = arg->pyarg;
++ Py_XINCREF(pyargsaved);
++ Py_XDECREF(arg->pyarg);
++ Py_DECREF(arg->pyfunc);
++ free(arg);
++
++ if (pyargsaved != NULL)
++ return (pyargsaved);
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(get_sap_doc,
++ "get_sap() -> unsigned int\n"
++ "\n"
++ "Returns the sap bound to this link.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_sap(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I", info.di_sap));
++}
++
++PyDoc_STRVAR(get_fd_doc,
++ "get_fd() -> int\n"
++ "\n"
++ "Returns the integer file descriptor that can be used to directly\n"
++ "operate on the link.\n"
++ "See dlpi_fd(3DLPI).\n"
++);
++static PyObject *
++link_get_fd(pylink_t *link)
++{
++ int fd;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((fd = dlpi_fd(link->dlpihdl)) == -1) {
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("i", fd));
++}
++
++PyDoc_STRVAR(get_linkname_doc,
++ "get_linkname() -> string\n"
++ "\n"
++ "Returns the name of the link.\n"
++ "See dlpi_linkname(3DLPI).\n"
++);
++static PyObject *
++link_get_linkname(pylink_t *link)
++{
++ const char *name = NULL;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((name = dlpi_linkname(link->dlpihdl)) == NULL) {
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("s", name));
++}
++
++PyDoc_STRVAR(get_bcastaddr_doc,
++ "get_bcastaddr() -> string, or None\n"
++ "\n"
++ "Returns the broadcast address of the link.\n"
++ "Returns None if the broadcast address is empty.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_bcastaddr(pylink_t *link)
++{
++ char *addr[DLPI_PHYSADDR_MAX];
++ size_t addrlen = 0;
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ if (info.di_bcastaddrlen == 0) {
++ Py_INCREF(Py_None);
++ return (Py_None);
++ }
++
++ return (Py_BuildValue("s#", info.di_bcastaddr, info.di_bcastaddrlen));
++}
++
++PyDoc_STRVAR(get_physaddr_doc,
++ "get_physaddr(addrtype) -> string, or None\n"
++ "\n"
++ "Addrtype can be any one of the value listed below:\n"
++ "FACT_PHYS_ADDR Factory physical address\n"
++ "CURR_PHYS_ADDR Current physical address\n"
++ "Returns the corresponding physical address of the link.\n"
++ "See dlpi_get_physaddr(3DLPI).\n"
++);
++static PyObject *
++link_get_physaddr(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ char *addr[DLPI_PHYSADDR_MAX];
++ size_t addrlen = DLPI_PHYSADDR_MAX;
++ static char *keywords[] = {"addrtype", NULL};
++ uint_t type;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", keywords, &type))
++ return (NULL);
++
++ if ((rval = dlpi_get_physaddr(link->dlpihdl, type, addr, &addrlen)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("s#", addr, addrlen));
++}
++
++PyDoc_STRVAR(set_physaddr_doc,
++ "set_physaddr(address) -> None\n"
++ "\n"
++ "Sets the physical address of the link.\n"
++ "See dlpi_set_physaddr(3DLPI).\n"
++);
++static PyObject *
++link_set_physaddr(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ char *addr = NULL;
++ size_t addrlen = 0;
++ static char *keywords[] = {"address", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#", keywords,
++ &addr, &addrlen))
++ return (NULL);
++
++ if ((rval = dlpi_set_physaddr(link->dlpihdl, DL_CURR_PHYS_ADDR,
++ addr, addrlen)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(promiscon_doc,
++ "promiscon([level]) -> None\n"
++ "\n"
++ "Enables promiscuous mode for the link at levels:\n"
++ "PROMISC_PHYS Promiscuous mode at the physical level(default)\n"
++ "PROMISC_SAP Promiscuous mode at the SAP level\n"
++ "PROMISC_MULTI Promiscuous mode for all multicast addresses\n"
++ "See dlpi_promiscon(3DLPI).\n"
++);
++static PyObject *
++link_promiscon(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ uint_t level = DL_PROMISC_PHYS;
++ static char *keywords[] = {"level", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|I", keywords, &level))
++ return (NULL);
++
++ if ((rval = dlpi_promiscon(link->dlpihdl, level)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(promiscoff_doc,
++ "promiscoff([level]) -> None\n"
++ "\n"
++ "Disables promiscuous mode for the link at levels:\n"
++ "PROMISC_PHYS Promiscuous mode at the physical level(default)\n"
++ "PROMISC_SAP Promiscuous mode at the SAP level\n"
++ "PROMISC_MULTI Promiscuous mode for all multicast addresses\n"
++ "See dlpi_promiscoff(3DLPI).\n"
++);
++static PyObject *
++link_promiscoff(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ uint_t level = DL_PROMISC_PHYS;
++ static char *keywords[] = {"level", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|I", keywords, &level))
++ return (NULL);
++
++ if ((rval = dlpi_promiscoff(link->dlpihdl, level)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(get_timeout_doc,
++ "get_timeout() -> int\n"
++ "\n"
++ "Returns current time out value of the link.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_timeout(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("i", info.di_timeout));
++}
++
++PyDoc_STRVAR(get_mactype_doc,
++ "get_mactype() -> unsigned char\n"
++ "\n"
++ "Returns MAC type of the link.\n"
++ "See <sys/dlpi.h> for the list of possible MAC types.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_mactype(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("B", info.di_mactype));
++}
++
++PyDoc_STRVAR(set_timeout_doc,
++ "set_timeout(timeout) -> None\n"
++ "\n"
++ "Sets time out value of the link (default value: DEF_TIMEOUT).\n"
++ "See dlpi_set_timeout(3DLPI).\n"
++);
++static PyObject *
++link_set_timeout(pylink_t *link, PyObject *args, PyObject *kwds)
++{
++ int timeout = DLPI_DEF_TIMEOUT;
++ static char *keywords[] = {"timeout", NULL};
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", keywords, &timeout))
++ return (NULL);
++
++ if ((rval = dlpi_set_timeout(link->dlpihdl, timeout)) != DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ Py_INCREF(Py_None);
++ return (Py_None);
++}
++
++PyDoc_STRVAR(get_sdu_doc,
++ "get_sdu() -> (unsigned int, unsigned int)\n"
++ "\n"
++ "Returns (min sdu, max sdu).\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_sdu(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("II", info.di_min_sdu, info.di_max_sdu));
++}
++
++PyDoc_STRVAR(get_state_doc,
++ "get_state() -> unsigned int\n"
++ "\n"
++ "Returns current state of the link (either UNBOUND or IDLE).\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_state(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I", info.di_state));
++}
++
++PyDoc_STRVAR(get_qos_select_doc,
++ "get_qos_select() -> (unsigned int, int, int, int)\n"
++ "\n"
++ "Returns (qos type, trans delay, priority, residul err).\n"
++ "Unsupported QOS parameters are set to UNKNOWN.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_qos_select(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("Iiiii",
++ info.di_qos_sel.dl_qos_type,
++ info.di_qos_sel.dl_trans_delay,
++ info.di_qos_sel.dl_priority,
++ info.di_qos_sel.dl_residual_error));
++}
++
++PyDoc_STRVAR(get_qos_range_doc,
++ "get_qos_range() -> \n"
++ " (unsigned int, (int, int), (int, int), (int, int), int)\n"
++ "\n"
++ "Returns (qos type, (trans delay target, trans delay accept),\n"
++ "(min priority, max priority), (min protection, max protection),\n"
++ "residual err).\n"
++ "Unsupported QOS range values are set to UNKNOWN.\n"
++ "See dlpi_info(3DLPI).\n"
++);
++static PyObject *
++link_get_qos_range(pylink_t *link)
++{
++ dlpi_info_t info;
++ int rval;
++
++ if (link->dlpihdl == NULL) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ if ((rval = dlpi_info(link->dlpihdl, &info, 0)) !=
++ DLPI_SUCCESS) {
++ dlpi_raise_exception(rval);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I(ii)(ii)(ii)i",
++ info.di_qos_range.dl_qos_type,
++ info.di_qos_range.dl_trans_delay.dl_target_value,
++ info.di_qos_range.dl_trans_delay.dl_accept_value,
++ info.di_qos_range.dl_priority.dl_min,
++ info.di_qos_range.dl_priority.dl_max,
++ info.di_qos_range.dl_protection.dl_min,
++ info.di_qos_range.dl_protection.dl_max,
++ info.di_qos_range.dl_residual_error));
++}
++
++static PyMethodDef pylink_methods[] = {
++ {"bind", (PyCFunction)link_bind, METH_VARARGS|METH_KEYWORDS, bind_doc},
++ {"unbind", (PyCFunction)link_unbind, METH_NOARGS, unbind_doc},
++ {"send", (PyCFunction)link_send, METH_VARARGS|METH_KEYWORDS,
++ send_doc},
++ {"recv", (PyCFunction)link_recv, METH_VARARGS|METH_KEYWORDS,
++ recv_doc},
++ {"disabmulti", (PyCFunction)link_disabmulti, METH_VARARGS|METH_KEYWORDS,
++ disabmulti_doc},
++ {"enabmulti", (PyCFunction)link_enabmulti, METH_VARARGS|METH_KEYWORDS,
++ enabmulti_doc},
++ {"enabnotify", (PyCFunction)link_enabnotify,
++ METH_VARARGS|METH_KEYWORDS, enabnotify_doc},
++ {"disabnotify", (PyCFunction)link_disabnotify,
++ METH_VARARGS|METH_KEYWORDS, disabnotify_doc},
++ {"get_fd", (PyCFunction)link_get_fd, METH_NOARGS, get_fd_doc},
++ {"get_sap", (PyCFunction)link_get_sap, METH_NOARGS, get_sap_doc},
++ {"get_mactype", (PyCFunction)link_get_mactype, METH_NOARGS,
++ get_mactype_doc},
++ {"get_linkname", (PyCFunction)link_get_linkname, METH_NOARGS,
++ get_linkname_doc},
++ {"get_bcastaddr", (PyCFunction)link_get_bcastaddr, METH_NOARGS,
++ get_bcastaddr_doc},
++ {"get_physaddr", (PyCFunction)link_get_physaddr,
++ METH_VARARGS|METH_KEYWORDS, get_physaddr_doc},
++ {"set_physaddr", (PyCFunction)link_set_physaddr,
++ METH_VARARGS|METH_KEYWORDS, set_physaddr_doc},
++ {"promiscon", (PyCFunction)link_promiscon, METH_VARARGS|METH_KEYWORDS,
++ promiscon_doc},
++ {"promiscoff", (PyCFunction)link_promiscoff, METH_VARARGS|METH_KEYWORDS,
++ promiscoff_doc},
++ {"get_timeout", (PyCFunction)link_get_timeout, METH_NOARGS,
++ get_timeout_doc},
++ {"set_timeout", (PyCFunction)link_set_timeout,
++ METH_VARARGS|METH_KEYWORDS, set_timeout_doc},
++ {"get_sdu", (PyCFunction)link_get_sdu, METH_NOARGS, get_sdu_doc},
++ {"get_state", (PyCFunction)link_get_state, METH_NOARGS,
++ get_state_doc},
++ {"get_qos_select", (PyCFunction)link_get_qos_select, METH_NOARGS,
++ get_qos_select_doc},
++ {"get_qos_range", (PyCFunction)link_get_qos_range, METH_NOARGS,
++ get_qos_range_doc},
++ {NULL, NULL}
++};
++
++static PyTypeObject pylink_type = {
++ PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */
++ "dlpi.link", /* tp_name */
++ sizeof(pylink_t), /* tp_basicsize */
++ 0, /* tp_itemsize */
++ (destructor)link_dealloc, /* tp_dealloc */
++ 0, /* tp_print */
++ 0, /* tp_getattr */
++ 0, /* tp_setattr */
++ 0, /* tp_reserved */
++ 0, /* tp_repr */
++ 0, /* tp_as_number */
++ 0, /* tp_as_sequence */
++ 0, /* tp_as_mapping */
++ 0, /* tp_hash */
++ 0, /* tp_call */
++ 0, /* tp_str */
++ 0, /* tp_getattro */
++ 0, /* tp_setattro */
++ 0, /* tp_as_buffer */
++ Py_TPFLAGS_DEFAULT, /* tp_flags */
++ link_doc, /* tp_doc */
++ 0, /* tp_traverse */
++ 0, /* tp_clear */
++ 0, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ 0, /* tp_iter */
++ 0, /* tp_iternext */
++ pylink_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ (initproc)link_init, /* tp_init */
++ 0, /* tp_alloc */
++ PyType_GenericNew, /* tp_new */
++ 0, /* tp_free */
++ 0, /* tp_is_gc */
++};
++
++PyDoc_STRVAR(arptype_doc,
++ "arptype(arptype) -> unsigned int\n"
++ "\n"
++ "Converts a DLPI MAC type to an ARP hardware type defined\n"
++ " in <netinet/arp.h>\n"
++ "See dlpi_arptype(3DLPI)\n"
++);
++static PyObject *
++arptype(PyObject *dlpi, PyObject *args, PyObject *kwds)
++{
++ static char *keywords[] = {"arptype", NULL};
++ uint_t dlpityp, arptyp;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", keywords, &dlpityp))
++ return (NULL);
++
++ if ((arptyp = dlpi_arptype(dlpityp)) == 0) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I", arptyp));
++}
++
++PyDoc_STRVAR(iftype_doc,
++ "iftype(iftype) -> unsigned int\n"
++ "\n"
++ "Converts a DLPI MAC type to a BSD socket interface type\n"
++ "defined in <net/if_types.h>\n"
++ "See dlpi_iftype(3DLPI)\n"
++);
++static PyObject *
++iftype(PyObject *dlpi, PyObject *args, PyObject *kwds)
++{
++ static char *keywords[] = {"iftype", NULL};
++ uint_t dlpityp, iftyp;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", keywords, &dlpityp))
++ return (NULL);
++
++ if ((iftyp = dlpi_iftype(dlpityp)) == 0) {
++ errno = EINVAL;
++ dlpi_raise_exception(DL_SYSERR);
++ return (NULL);
++ }
++
++ return (Py_BuildValue("I", iftyp));
++}
++
++PyDoc_STRVAR(mactype_doc,
++ "mactype(mactype) -> string\n"
++ "\n"
++ "Returns a string that describes the specified mactype.\n"
++ "Valid mac types are defined in <sys/dlpi.h>.\n"
++ "See dlpi_mactype(3DLPI)\n"
++);
++static PyObject *
++mactype(PyObject *dlpi, PyObject *args, PyObject *kwds)
++{
++ static char *keywords[] = {"mactype", NULL};
++ uint_t mactyp;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", keywords, &mactyp))
++ return (NULL);
++
++ return (Py_BuildValue("s", dlpi_mactype(mactyp)));
++}
++
++static boolean_t
++link_walker(const char *name, void *arg)
++{
++ PyObject *linkname;
++ PyObject *list = (PyObject *)arg;
++
++ if ((list == NULL) || !PyList_Check(list))
++ return (B_FALSE);
++
++ linkname = Py_BuildValue("s", name);
++ if (PyList_Append(list, linkname) == -1)
++ return (B_TRUE);
++
++ Py_DECREF(linkname);
++ return (B_FALSE);
++}
++
++PyDoc_STRVAR(listlink_doc,
++ "listlink() -> list\n"
++ "\n"
++ "Returns a list containing link names of all links on the system.\n"
++);
++static PyObject *
++listlink(PyObject *dlpi)
++{
++ PyObject *list;
++
++ if ((list = PyList_New(0)) == NULL)
++ return (NULL);
++
++ dlpi_walk(link_walker, list, 0);
++ return (list);
++}
++
++static PyMethodDef dlpi_methods[] = {
++ {"arptype", (PyCFunction)arptype, METH_VARARGS|METH_KEYWORDS,
++ arptype_doc},
++ {"iftype", (PyCFunction)iftype, METH_VARARGS|METH_KEYWORDS,
++ iftype_doc},
++ {"mactype", (PyCFunction)mactype, METH_VARARGS|METH_KEYWORDS,
++ mactype_doc},
++ {"listlink", (PyCFunction)listlink, METH_NOARGS, listlink_doc},
++ {NULL}
++};
++
++PyMODINIT_FUNC
++PyInit_dlpi (void)
++{
++ PyObject *mod;
++
++ if (PyType_Ready(&pylink_type) < 0)
++ return NULL;
++
++ static struct PyModuleDef moduledef = {
++ PyModuleDef_HEAD_INIT,
++ "dlpi",
++ NULL,
++ -1,
++ dlpi_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ };
++
++ mod = PyModule_Create(&moduledef);
++ if (mod == NULL)
++ return NULL;
++
++ dlpi_err = PyErr_NewException("dlpi.error", NULL, NULL);
++ if (dlpi_err == NULL)
++ return NULL;
++ PyModule_AddObject(mod, "error", dlpi_err);
++
++ Py_INCREF(&pylink_type);
++ PyModule_AddObject(mod, "link", (PyObject *)&pylink_type);
++ PyModule_AddIntConstant(mod, "PASSIVE", DLPI_PASSIVE);
++ PyModule_AddIntConstant(mod, "RAW", DLPI_RAW);
++ PyModule_AddIntConstant(mod, "NATIVE", DLPI_NATIVE);
++ PyModule_AddIntConstant(mod, "ANY_SAP", DLPI_ANY_SAP);
++ PyModule_AddIntConstant(mod, "DEF_TIMEOUT", DLPI_DEF_TIMEOUT);
++ PyModule_AddIntConstant(mod, "NOTE_LINK_DOWN", DL_NOTE_LINK_DOWN);
++ PyModule_AddIntConstant(mod, "NOTE_LINK_UP", DL_NOTE_LINK_UP);
++ PyModule_AddIntConstant(mod, "NOTE_PHYS_ADDR", DL_NOTE_PHYS_ADDR);
++ PyModule_AddIntConstant(mod, "NOTE_SDU_SIZE", DL_NOTE_SDU_SIZE);
++ PyModule_AddIntConstant(mod, "NOTE_SPEED", DL_NOTE_SPEED);
++ PyModule_AddIntConstant(mod, "NOTE_PROMISC_ON_PHYS",
++ DL_NOTE_PROMISC_ON_PHYS);
++ PyModule_AddIntConstant(mod, "NOTE_PROMISC_OFF_PHYS",
++ DL_NOTE_PROMISC_OFF_PHYS);
++ PyModule_AddIntConstant(mod, "FACT_PHYS_ADDR", DL_FACT_PHYS_ADDR);
++ PyModule_AddIntConstant(mod, "CURR_PHYS_ADDR", DL_CURR_PHYS_ADDR);
++ PyModule_AddIntConstant(mod, "PROMISC_PHYS", DL_PROMISC_PHYS);
++ PyModule_AddIntConstant(mod, "PROMISC_SAP", DL_PROMISC_SAP);
++ PyModule_AddIntConstant(mod, "PROMISC_MULTI", DL_PROMISC_MULTI);
++ PyModule_AddIntConstant(mod, "UNKNOWN", DL_UNKNOWN);
++ PyModule_AddIntConstant(mod, "UNBOUND", DL_UNBOUND);
++ PyModule_AddIntConstant(mod, "IDLE", DL_IDLE);
++ PyModule_AddIntConstant(mod, "SYSERR", DL_SYSERR);
++
++ return mod;
++}
+--- Python-3.5.0a4/setup.py.~4~ 2015-04-20 13:28:29.633806027 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:28:29.649896175 -0700
[email protected]@ -1539,6 +1539,12 @@
+ exts.append( Extension('ucred', ['ucred.c'],
+ libraries = ['tsol']) )
+
++ # dlpi module (Solaris)
++ dlpi_inc = find_file('libdlpi.h', [], inc_dirs)
++ if dlpi_inc is not None:
++ exts.append( Extension('dlpi', ['dlpimodule.c'],
++ libraries = ['dlpi']) )
++
+ # Thomas Heller's _ctypes module
+ self.detect_ctypes(inc_dirs, lib_dirs)
+
+--- /dev/null 2011-02-12 03:13:26.000000000 -0600
++++ Python-2.6.4/Lib/test/dlpitest.py 2011-01-20 13:52:42.895865414 -0600
[email protected]@ -0,0 +1,96 @@
++#!/usr/bin/python3.5
++
++import dlpi
++import sys
++import time
++import struct
++
++#test listlink
++linklist = dlpi.listlink()
++print("Found %d links:" % len(linklist))
++print(linklist)
++
++#pick up the first data link for below testing
++linkname = linklist[0]
++
++#open link
++print("opening link: " + linkname + "...")
++testlink = dlpi.link(linkname)
++
++#read some info of testlink
++print("linkname is %s" % testlink.get_linkname())
++print("link fd is %d" % testlink.get_fd())
++mactype = testlink.get_mactype()
++print("dlpi mactype is %d" % mactype)
++print("after convert:")
++print("\tmactype is %s" % dlpi.mactype(mactype))
++print("\tiftype is %d" % dlpi.iftype(mactype))
++print("\tarptype is %d" % dlpi.arptype(mactype))
++bcastaddr = testlink.get_bcastaddr()
++print("broadcast addr is: ", end=' ')
++print(struct.unpack("BBBBBB",bcastaddr))
++physaddr = testlink.get_physaddr(dlpi.FACT_PHYS_ADDR)
++print("factory physical address is: ", end=' ')
++print(struct.unpack("BBBBBB",physaddr))
++print("current timeout value is %d" % testlink.get_timeout())
++print("sdu is:", end=' ')
++print(testlink.get_sdu())
++print("qos select is:", end=' ')
++print(testlink.get_qos_select())
++print("qos range is:", end=' ')
++print(testlink.get_qos_range())
++
++#set some config value of testlink and read them again
++print("setting current physiacal addr to aa:0:10:13:27:5")
++testlink.set_physaddr('\xaa\0\x10\x13\x27\5')
++physaddr = testlink.get_physaddr(dlpi.CURR_PHYS_ADDR)
++print("current physical addr is: ", end=' ')
++print(struct.unpack("BBBBBB",physaddr))
++print("set timeout value to 6...")
++testlink.set_timeout(6)
++print("timeout value is %d" % testlink.get_timeout())
++
++#test enable/disable multicast
++print("enable/disable multicast address 1:0:5e:0:0:5")
++testlink.enabmulti('\1\0\x5e\0\0\5')
++testlink.disabmulti('\1\0\x5e\0\0\5')
++
++#test bind
++print("binding to SAP 0x9000...")
++testlink.bind(0x9000)
++print("sap is %x" % testlink.get_sap())
++print("state is: %d" % testlink.get_state())
++
++#test send
++print("sending broadcast loopback packet...")
++testlink.send(bcastaddr, '\0\1\2\3\4\5')
++
++#test notify functionality
++arg = "notification callback arg"
++def notify(arg, notes, value):
++ print("NOTE_PROMISC_ON_PHYS notification received with arg: '%s'" % arg)
++print("enabled notification on NOTE_PROMISC_ON_PHYS")
++id = testlink.enabnotify(dlpi.NOTE_PROMISC_ON_PHYS, notify, arg) #enable notification
++testlink.promiscon() #trigger the event (will be seen while receiving pkt below)
++
++#test receive
++print("testing receiving...")
++try:
++ testlink.recv(0, 0) #should see NOTE_PROMISC_ON_PHYS event here
++except dlpi.error as err:
++ errnum, errinfo = err
++ if errnum == 10006:
++ pass #timeout error is expected here
++ else: #test fails if reach here
++ print("test failed", end=' ')
++ print(errnum, end=' ')
++ print(err)
++
++testlink.promiscoff()
++testlink.disabnotify(id) #disable notification
++
++#test unbind
++print("unbinding...")
++testlink.unbind()
++print("sap is %x" % testlink.get_sap())
++print("state is: %d" % testlink.get_state())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/09-encoding-alias.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,37 @@
+Add missing encoding aliases. It may be contributed upstream at some point,
+but the suitability (or lack thereof) has not yet been determined.
+
+--- Python-3.5.0rc2/Lib/encodings/aliases.py.~1~ 2015-08-25 10:19:12.000000000 -0700
++++ Python-3.5.0rc2/Lib/encodings/aliases.py 2015-09-02 12:27:47.142334449 -0700
[email protected]@ -79,6 +79,7 @@
+
+ # cp1251 codec
+ '1251' : 'cp1251',
++ 'ansi_1251' : 'cp1251',
+ 'windows_1251' : 'cp1251',
+
+ # cp1252 codec
[email protected]@ -233,6 +234,7 @@
+ 'u_jis' : 'euc_jp',
+
+ # euc_kr codec
++ '5601' : 'euc_kr',
+ 'euckr' : 'euc_kr',
+ 'korean' : 'euc_kr',
+ 'ksc5601' : 'euc_kr',
[email protected]@ -479,6 +481,7 @@
+ 'shiftjis' : 'shift_jis',
+ 'sjis' : 'shift_jis',
+ 's_jis' : 'shift_jis',
++ 'pck' : 'shift_jis',
+
+ # shift_jis_2004 codec
+ 'shiftjis2004' : 'shift_jis_2004',
[email protected]@ -498,6 +501,7 @@
+ 'tis_620_0' : 'tis_620',
+ 'tis_620_2529_0' : 'tis_620',
+ 'tis_620_2529_1' : 'tis_620',
++ 'tis620.2533' : 'tis_620',
+ 'iso_ir_166' : 'tis_620',
+
+ # utf_16 codec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/10-rbac.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,1602 @@
+This patch provides Python RBAC support. It may be contributed upstream at
+some point, but the suitability (or lack thereof) has not yet been determined.
+
+diff --git Python-2.6.4/Modules/authattr.c Python-2.6.4/Modules/authattr.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/authattr.c
[email protected]@ -0,0 +1,261 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * RBAC Bindings for Python - auth_attr functions
++ */
++
++#include <auth_attr.h>
++#include "Python.h"
++#include "pyrbac.h"
++
++static PyObject*
++pyrbac_setauthattr(PyObject* self, PyObject* args) {
++ setauthattr();
++ return Py_None;
++}
++
++static PyObject*
++pyrbac_endauthattr(PyObject* self, PyObject* args) {
++ endauthattr();
++ return Py_None;
++}
++
++PyObject*
++pyrbac_getauthnamattr(PyObject* self, char* authname, int mode) {
++
++
++
++ authattr_t * ret_authattr = (mode == PYRBAC_NAM_MODE) ? getauthnam(authname) : getauthattr();
++ if (ret_authattr == NULL)
++ return Py_None;
++
++ PyObject* kv_data = PyDict_New();
++ if (kv_data == NULL) {
++ free_authattr(ret_authattr);
++ return NULL;
++ }
++
++ if(ret_authattr->attr != NULL) {
++ int len;
++ for(len = 0; len < ret_authattr->attr->length; len++) {
++ kv_t current = ret_authattr->attr->data[len];
++
++ PyObject* set = PyList_New(NULL);
++ char* saveptr;
++ char* item = strtok_r(current.value, ",", &saveptr);
++ PyList_Append(set, PyBytes_FromString(item));
++
++ while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
++ if(PyList_Append(set, PyBytes_FromString(item)) != 0) {
++ Py_XDECREF(set);
++ Py_XDECREF(kv_data);
++ free_authattr(ret_authattr);
++ return NULL;
++ }
++ }
++ if(PyDict_SetItemString(kv_data, current.key, set)) {
++ free_authattr(ret_authattr);
++ return NULL;
++ }
++ }
++ }
++ PyObject * retval = Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:O}",
++ "name",ret_authattr->name,
++ "res1",ret_authattr->res1,
++ "res2",ret_authattr->res2,
++ "short",ret_authattr->short_desc,
++ "long",ret_authattr->long_desc,
++ "attributes",kv_data);
++
++ free_authattr(ret_authattr);
++ return retval;
++
++}
++
++static PyObject*
++pyrbac_getauthattr(PyObject* self, PyObject* args) {
++ return(pyrbac_getauthnamattr(self, NULL, PYRBAC_ATTR_MODE));
++}
++
++static PyObject*
++pyrbac_getauthnam(PyObject* self, PyObject* args) {
++ char* name = NULL;
++ if(!PyArg_ParseTuple(args, "s:getauthnam", &name))
++ return NULL;
++ return(pyrbac_getauthnamattr(self, name, PYRBAC_NAM_MODE));
++}
++
++static PyObject *
++pyrbac_chkauthattr(PyObject* self, PyObject* args) {
++ char* authstring = NULL;
++ char* username = NULL;
++ if(!PyArg_ParseTuple(args, "ss:chkauthattr", &authstring, &username))
++ return NULL;
++ return PyBool_FromLong((long)chkauthattr(authstring, username));
++}
++
++static PyObject*
++pyrbac_authattr_next(PyObject* self, PyObject* args) {
++ PyObject* retval = pyrbac_getauthattr(self, args);
++ if( retval == Py_None ) {
++ setauthattr();
++ return NULL;
++ }
++ return retval;
++}
++static PyObject*
++pyrbac_authattr__iter__(PyObject* self, PyObject* args) {
++ return self;
++}
++
++typedef struct {
++ PyObject_HEAD
++} Authattr;
++
++static void
++Authattr_dealloc(Authattr* self) {
++ endauthattr();
++ Py_TYPE(self)->tp_free((PyObject*) self);
++}
++
++static PyObject*
++Authattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
++ Authattr *self;
++ self = (Authattr*)type->tp_alloc(type, 0);
++
++ return ((PyObject *) self);
++}
++
++static int
++Authattr_init(Authattr* self, PyObject *args, PyObject *kwargs) {
++ setauthattr();
++ return 0;
++}
++
++static char pyrbac_authattr__doc__[];
++
++PyDoc_STRVAR(pyrbac_authattr__doc__, """provides interfaces to the auth_attr \
++database. may be iterated over to return all auth_attr entries\n\n\
++Methods provided:\n\
++setauthattr\n\
++endauthattr\n\
++getauthattr\n\
++chkauthattr\n\
++getauthnam""");
++
++static char pyrbac_setauthattr__doc__[];
++static char pyrbac_endauthattr__doc__[];
++static char pyrbac_getauthattr__doc__[];
++static char pyrbac_chkauthattr__doc__[];
++
++PyDoc_STRVAR(pyrbac_setauthattr__doc__,
++"\"rewinds\" the auth_attr functions to the first entry in the db. Called \
++automatically by the constructor\n\tArguments: None\n\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_endauthattr__doc__,
++"closes the auth_attr database, cleans up storage. called automatically by \
++the destructor\n\tArguments: None\n\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_chkauthattr__doc__, "verifies if a user has a given \
++authorization.\n\tArguments: 2 Python strings, 'authname' and 'username'\n\
++\tReturns: True if the user is authorized, False otherwise");
++
++PyDoc_STRVAR(pyrbac_getauthattr__doc__,
++"return one entry from the auth_attr database\n\
++\tArguments: None\n\
++\tReturns: a dict representing the authattr_t struct:\n\
++\t\t\"name\": Authorization Name\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"short\": Short Description\n\
++\t\t\"long\": Long Description\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value");
++
++PyDoc_STRVAR(pyrbac_getauthnam__doc__,
++"searches the auth_attr database for a given authorization name\n\
++\tArguments: a Python string containing the auth name\n\
++\tReturns: a dict representing the authattr_t struct:\n\
++\t\t\"name\": Authorization Name\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"short\": Short Description\n\
++\t\t\"long\": Long Description\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value");
++
++static PyMethodDef Authattr_methods[] = {
++ {"setauthattr", pyrbac_setauthattr, METH_NOARGS, pyrbac_setauthattr__doc__},
++ {"endauthattr", pyrbac_endauthattr, METH_NOARGS, pyrbac_endauthattr__doc__},
++ {"chkauthattr", pyrbac_chkauthattr, METH_VARARGS, pyrbac_chkauthattr__doc__},
++ {"getauthattr", pyrbac_getauthattr, METH_NOARGS, pyrbac_getauthattr__doc__},
++ {"getauthnam", pyrbac_getauthnam, METH_VARARGS, pyrbac_getauthnam__doc__},
++ {NULL, NULL}
++};
++
++PyTypeObject AuthattrType = {
++ PyVarObject_HEAD_INIT(NULL, 0)
++ "rbac.authattr", /*tp_name*/
++ sizeof(Authattr), /*tp_basicsize*/
++ 0, /*tp_itemsize*/
++ (destructor)Authattr_dealloc, /*tp_dealloc*/
++ 0, /*tp_print*/
++ 0, /*tp_getattr*/
++ 0, /*tp_setattr*/
++ 0, /*tp_reserved*/
++ 0, /*tp_repr*/
++ 0, /*tp_as_number*/
++ 0, /*tp_as_sequence*/
++ 0, /*tp_as_mapping*/
++ 0, /*tp_hash */
++ 0, /*tp_call*/
++ 0, /*tp_str*/
++ 0, /*tp_getattro*/
++ 0, /*tp_setattro*/
++ 0, /*tp_as_buffer*/
++ Py_TPFLAGS_DEFAULT |
++ Py_TPFLAGS_BASETYPE, /*tp_flags*/
++ pyrbac_authattr__doc__, /* tp_doc */
++ 0, /* tp_traverse */
++ 0, /* tp_clear */
++ 0, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ pyrbac_authattr__iter__, /* tp_iter */
++ pyrbac_authattr_next, /* tp_iternext */
++ Authattr_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ (initproc)Authattr_init, /* tp_init */
++ 0, /* tp_alloc */
++ Authattr_new, /* tp_new */
++ 0, /* tp_free */
++ 0, /* tp_is_gc */
++};
+diff --git Python-2.6.4/Modules/execattr.c Python-2.6.4/Modules/execattr.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/execattr.c
[email protected]@ -0,0 +1,313 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * RBAC Bindings for Python - exec_attr functions
++ */
++
++#include <exec_attr.h>
++#include "Python.h"
++#include "pyrbac.h"
++
++static PyObject *
++pyrbac_setexecattr(PyObject* self, PyObject* args) {
++ setexecattr();
++ return Py_None;
++}
++
++static PyObject *
++pyrbac_endexecattr(PyObject* self, PyObject* args) {
++ endexecattr();
++ return Py_None;
++}
++
++PyObject *
++pyrbac_getexecuserprofattr(PyObject* self, char* userprofname, char* type, char* id, int mode) {
++
++ PyObject* ep_data = (mode == PYRBAC_ATTR_MODE) ? NULL : PyList_New(0);
++
++ if (ep_data == NULL && mode != PYRBAC_ATTR_MODE )
++ return NULL;
++
++ execattr_t *execprof;
++ if (mode == PYRBAC_USER_MODE)
++ execprof = getexecuser(userprofname, type, id, GET_ALL);
++ else if (mode == PYRBAC_PROF_MODE)
++ execprof = getexecprof(userprofname, type, id, GET_ALL);
++ else if (mode == PYRBAC_ATTR_MODE)
++ execprof = getexecattr();
++ else
++ return NULL;
++
++ if (execprof == NULL)
++ return Py_None;
++
++ execattr_t *execprof_head = execprof;
++
++ while(execprof != NULL) {
++
++ PyObject* kv_data = PyDict_New();
++
++ if(execprof->attr != NULL) {
++ int len;
++ for(len = 0; len < execprof->attr->length; len++) {
++ kv_t current = execprof->attr->data[len];
++
++ PyObject* set = PyList_New(NULL);
++ char* saveptr;
++ char* item = strtok_r(current.value, ",", &saveptr);
++ PyList_Append(set, PyBytes_FromString(item));
++
++ while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
++ if(PyList_Append(set, PyBytes_FromString(item)) != 0) {
++ Py_XDECREF(set);
++ Py_XDECREF(kv_data);
++ free_execattr(execprof_head);
++ return NULL;
++ }
++ }
++ if(PyDict_SetItemString(kv_data, current.key, set)) {
++ free_execattr(execprof_head);
++ return NULL;
++ }
++ }
++ }
++ PyObject* entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:s,s:O}",
++ "name", execprof->name,
++ "type", execprof->type,
++ "policy", execprof->policy,
++ "res1", execprof->res1,
++ "res2", execprof->res2,
++ "id", execprof->id,
++ "attributes", kv_data);
++
++ if (entry == NULL) {
++ Py_XDECREF(kv_data);
++ free_execattr(execprof_head);
++ return NULL;
++ }
++
++ if (mode == PYRBAC_ATTR_MODE) {
++ free_execattr(execprof_head);
++ return(entry);
++ }
++ PyList_Append(ep_data, entry);
++ execprof = execprof->next;
++ }
++
++ free_execattr(execprof_head);
++ return(ep_data);
++
++}
++
++static PyObject *
++pyrbac_getexecuser(PyObject* self, PyObject* args) {
++ char* username = NULL;
++ char* type = NULL;
++ char* id = NULL;
++
++ if(!PyArg_ParseTuple(args, "sss:getexecuser", &username, &type, &id))
++ return NULL;
++
++ return (pyrbac_getexecuserprofattr(self, username, type, id, PYRBAC_USER_MODE));
++}
++
++static PyObject *
++pyrbac_getexecprof(PyObject* self, PyObject* args) {
++
++ char* profname = NULL;
++ char* type = NULL;
++ char* id = NULL;
++
++ if(!PyArg_ParseTuple(args, "sss:getexecprof", &profname, &type, &id))
++ return NULL;
++
++ return (pyrbac_getexecuserprofattr(self, profname, type, id, PYRBAC_PROF_MODE));
++}
++
++static PyObject*
++pyrbac_getexecattr(PyObject* self, PyObject* args) {
++ return pyrbac_getexecuserprofattr(self, NULL, NULL, NULL, PYRBAC_ATTR_MODE);
++}
++
++static PyObject*
++pyrbac_execattr_next(PyObject* self, PyObject* args) {
++ PyObject* retval = pyrbac_getexecattr(self, args);
++ if( retval == Py_None ) {
++ setexecattr();
++ return NULL;
++ }
++ return retval;
++}
++static PyObject*
++pyrbac_execattr__iter__(PyObject* self, PyObject* args) {
++ return self;
++}
++
++typedef struct {
++ PyObject_HEAD
++} Execattr;
++
++static void
++Execattr_dealloc(Execattr* self) {
++ endexecattr();
++ Py_TYPE(self)->tp_free((PyObject*) self);
++}
++
++static PyObject*
++Execattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
++ Execattr *self;
++ self = (Execattr*)type->tp_alloc(type, 0);
++
++ return ((PyObject *) self);
++}
++
++static int
++Execattr_init(Execattr* self, PyObject *args, PyObject *kwargs) {
++ setexecattr();
++ return 0;
++}
++
++static char pyrbac_execattr__doc__[];
++
++PyDoc_STRVAR(pyrbac_execattr__doc__, "provides functions for \
++interacting with the execution profiles database. May be iterated over to \
++enumerate exec_attr(4) entries\n\n\
++Methods provided:\n\
++setexecattr\n\
++endexecattr\n\
++getexecattr\n\
++getexecprof\n\
++getexecuser");
++
++
++static char pyrbac_getexecuser__doc__[];
++static char pyrbac_getexecprof__doc__[];
++static char pyrbac_getexecattr__doc__[];
++static char pyrbac_setexecattr__doc__[];
++static char pyrbac_endexecattr__doc__[];
++
++PyDoc_STRVAR(pyrbac_setexecattr__doc__,
++"\"rewinds\" the exec_attr functions to the first entry in the db. Called \
++automatically by the constructor.\n\
++\tArguments: None\
++\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_endexecattr__doc__,
++"closes the exec_attr database, cleans up storage. called automatically by \
++the destructor.\n\
++\tArguments: None\
++\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_getexecuser__doc__, "corresponds with getexecuser(3SECDB)\
++\nTakes: \'username\', \'type\', \'id\'\n\
++Return: a single exec_attr entry\n\
++\tArguments: None\n\
++\tReturns: a dict representation of an execattr_t struct:\n\
++\t\t\"name\": Authorization Name\n\
++\t\t\"type\": Profile Type\n\
++\t\t\"policy\": Policy attributes are relevant in\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"id\": unique identifier\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as\
++either a list or a string depending on value");
++
++PyDoc_STRVAR(pyrbac_getexecprof__doc__, "corresponds with getexecprof(3SECDB)\
++\nTakes: \'profile name\', \'type\', \'id\'\n\
++\tReturns: a dict representation of an execattr_t struct:\n\
++\t\t\"name\": Authorization Name\n\
++\t\t\"type\": Profile Type\n\
++\t\t\"policy\": Policy attributes are relevant in\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"id\": unique identifier\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as\
++either a list or a string depending on value");
++
++PyDoc_STRVAR(pyrbac_getexecattr__doc__, "corresponds with getexecattr(3SECDB)\
++\nTakes 0 arguments\n\
++\tReturns: a dict representation of an execattr_t struct:\n\
++\t\t\"name\": Authorization Name\n\
++\t\t\"type\": Profile Type\n\
++\t\t\"policy\": Policy attributes are relevant in\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"id\": unique identifier\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as\
++either a list or a string depending on value");
++
++static PyMethodDef Execattr_methods[] = {
++ {"setexecattr", pyrbac_setexecattr, METH_NOARGS, pyrbac_setexecattr__doc__},
++ {"endexecattr", pyrbac_endexecattr, METH_NOARGS, pyrbac_endexecattr__doc__},
++ {"getexecprof", pyrbac_getexecprof, METH_VARARGS, pyrbac_getexecprof__doc__},
++ {"getexecuser", pyrbac_getexecuser, METH_VARARGS, pyrbac_getexecuser__doc__},
++ {"getexecattr", pyrbac_getexecattr, METH_NOARGS, pyrbac_getexecattr__doc__},
++ {NULL, NULL}
++};
++
++PyTypeObject ExecattrType = {
++ PyVarObject_HEAD_INIT(NULL, 0)
++ "rbac.execattr", /*tp_name*/
++ sizeof(Execattr), /*tp_basicsize*/
++ 0, /*tp_itemsize*/
++ (destructor)Execattr_dealloc, /*tp_dealloc*/
++ 0, /*tp_print*/
++ 0, /*tp_getattr*/
++ 0, /*tp_setattr*/
++ 0, /*tp_reserved*/
++ 0, /*tp_repr*/
++ 0, /*tp_as_number*/
++ 0, /*tp_as_sequence*/
++ 0, /*tp_as_mapping*/
++ 0, /*tp_hash */
++ 0, /*tp_call*/
++ 0, /*tp_str*/
++ 0, /*tp_getattro*/
++ 0, /*tp_setattro*/
++ 0, /*tp_as_buffer*/
++ Py_TPFLAGS_DEFAULT |
++ Py_TPFLAGS_BASETYPE, /*tp_flags*/
++ pyrbac_execattr__doc__, /* tp_doc */
++ 0, /* tp_traverse */
++ 0, /* tp_clear */
++ 0, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ pyrbac_execattr__iter__, /* tp_iter */
++ pyrbac_execattr_next, /* tp_iternext */
++ Execattr_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ (initproc)Execattr_init, /* tp_init */
++ 0, /* tp_alloc */
++ Execattr_new, /* tp_new */
++ 0, /* tp_free */
++ 0, /* tp_is_gc */
++};
+diff --git Python-2.6.4/Modules/privileges.c Python-2.6.4/Modules/privileges.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/privileges.c
[email protected]@ -0,0 +1,243 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * privileges(5) bindings for Python
++ */
++
++#include <priv.h>
++#include "Python.h"
++
++static PyObject *
++pyprivileges_setppriv( PyObject *self, PyObject *args) {
++ priv_op_t op = -1 ;
++ priv_ptype_t which = NULL;
++
++ PyObject* set_list = NULL;
++
++ priv_set_t * set = NULL;
++
++ if(!PyArg_ParseTuple(args, "iiO:setppriv", &op, &which, &set_list))
++ return NULL;
++
++ if((op != PRIV_ON && op != PRIV_OFF && op != PRIV_SET) ||
++ (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
++ which != PRIV_INHERITABLE && which != PRIV_LIMIT))
++ return NULL;
++
++ PyObject* set_string = PyList_GetItem(set_list, 0);
++ int i;
++ for (i = 1; i < PyList_Size(set_list); ++i) {
++ PyBytes_Concat(&set_string, PyBytes_FromString(","));
++ PyBytes_Concat(&set_string, PyList_GetItem(set_list, i));
++ }
++
++ set = priv_str_to_set(PyBytes_AsString(set_string), ",", NULL );
++
++ if ( set == NULL )
++ return NULL;
++
++ long ret = (long) setppriv(op, which, set);
++ priv_freeset(set);
++ // Python inverts true & false
++ if(ret)
++ Py_RETURN_FALSE;
++
++ Py_RETURN_TRUE;
++}
++
++static PyObject *
++pyprivileges_getppriv( PyObject *self, PyObject *args) {
++
++ char* set_str = NULL;
++ priv_ptype_t which = NULL;
++ priv_set_t * set = priv_allocset();
++ if (set == NULL)
++ return NULL;
++
++ if(!PyArg_ParseTuple(args, "i:getppriv", &which))
++ return NULL;
++
++ if (which != PRIV_PERMITTED && which != PRIV_EFFECTIVE &&
++ which != PRIV_INHERITABLE && which != PRIV_LIMIT)
++ return NULL;
++
++ if (getppriv(which, set) != 0)
++ return NULL;
++
++ set_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
++ priv_freeset(set);
++
++ PyObject* set_list = PyList_New(NULL);
++ char* saveptr;
++ char* item = strtok_r(set_str, ",", &saveptr);
++ PyList_Append(set_list, PyBytes_FromString(item));
++
++ while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
++ if(PyList_Append(set_list, PyBytes_FromString(item)) != 0) {
++ Py_XDECREF(set_list);
++ return NULL;
++ }
++ }
++
++ return(set_list);
++}
++
++static PyObject *
++pyprivileges_priv_inverse( PyObject *self, PyObject *args ) {
++
++ PyObject* set_list_in = NULL;
++ if(!PyArg_ParseTuple(args, "O:priv_inverse", &set_list_in))
++ return NULL;
++
++ PyObject* set_string = PyList_GetItem(set_list_in, 0);
++ int i;
++ for (i = 1; i < PyList_Size(set_list_in); ++i) {
++ PyBytes_Concat(set_string, PyBytes_FromString(","));
++ PyBytes_Concat(set_string, PyList_GetItem(set_list_in, i));
++ }
++
++ priv_set_t * set = priv_str_to_set(PyBytes_AsString(set_string), ",", NULL);
++ if (set == NULL)
++ return NULL;
++ priv_inverse(set);
++ char * ret_str = priv_set_to_str(set, ',', PRIV_STR_LIT);
++ priv_freeset(set);
++
++ PyObject* set_list_out = PyList_New(NULL);
++ char* saveptr;
++ char* item = strtok_r(ret_str, ",", &saveptr);
++ PyList_Append(set_list_out, PyBytes_FromString(item));
++
++ while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
++ if(PyList_Append(set_list_out, PyBytes_FromString(item)) != 0) {
++ Py_XDECREF(set_list_out);
++ return NULL;
++ }
++ }
++
++ Py_XDECREF(set_list_in);
++
++ return(set_list_out);
++}
++
++/* priv_ineffect is a convienient wrapper to priv_get
++ * however priv_set is, in the context of python, not
++ * much of a convienience, so it's omitted
++ */
++static PyObject *
++pyprivileges_priv_ineffect(PyObject* self, PyObject* args) {
++ char* privstring=NULL;
++ if (!PyArg_ParseTuple(args, "s:priv_ineffect", &privstring))
++ return NULL;
++ return PyBool_FromLong(priv_ineffect(privstring));
++}
++
++
++static char pyprivileges__doc__[];
++PyDoc_STRVAR(pyprivileges__doc__,
++"Provides functions for interacting with the Solaris privileges(5) framework\n\
++Functions provided:\n\
++setppriv\n\
++getppriv\n\
++priv_ineffect\n\
++priv_inverse");
++
++static char pyprivileges_setppriv__doc__[];
++static char pyprivileges_getppriv__doc__[];
++static char pyprivileges_priv_ineffect__doc__[];
++static char pyprivileges_priv_inverse__doc__[];
++
++PyDoc_STRVAR(pyprivileges_setppriv__doc__,
++"Facilitates setting the permitted/inheritable/limit/effective privileges set\n\
++\tArguments:\n\
++\t\tone of (PRIV_ON|PRIV_OFF|PRIV_SET)\n\
++\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
++\t\tset of privileges: a list of strings\n\
++\tReturns: True on success, False on failure\
++");
++
++PyDoc_STRVAR(pyprivileges_getppriv__doc__,
++"Return the process privilege set\n\
++\tArguments:\n\
++\t\tone of (PRIV_PERMITTED|PRIV_INHERITABLE|PRIV_LIMIT|PRIV_EFFECTIVE)\n\
++\tReturns: a Python list of strings");
++
++PyDoc_STRVAR(pyprivileges_priv_ineffect__doc__,
++"Checks for a privileges presence in the effective set\n\
++\tArguments: a String\n\
++\tReturns: True if the privilege is in effect, False otherwise");
++
++PyDoc_STRVAR(pyprivileges_priv_inverse__doc__,
++"The complement of the set of privileges\n\
++\tArguments: a list of strings\n\tReturns: a list of strings");
++
++static PyMethodDef module_methods[] = {
++ {"setppriv", pyprivileges_setppriv, METH_VARARGS, pyprivileges_setppriv__doc__},
++ {"getppriv", pyprivileges_getppriv, METH_VARARGS, pyprivileges_getppriv__doc__},
++ {"priv_ineffect", pyprivileges_priv_ineffect, METH_VARARGS, pyprivileges_priv_ineffect__doc__},
++ {"priv_inverse", pyprivileges_priv_inverse, METH_VARARGS, pyprivileges_priv_inverse__doc__},
++ {NULL, NULL}
++};
++
++
++#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
++#define PyMODINIT_FUNC void
++#endif
++PyMODINIT_FUNC
++PyInit_privileges (void) {
++ PyObject* m;
++
++ static struct PyModuleDef moduledef = {
++ PyModuleDef_HEAD_INIT,
++ "privileges",
++ pyprivileges__doc__,
++ -1,
++ module_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ };
++
++ m = PyModule_Create(&moduledef);
++ if ( m == NULL )
++ return m;
++
++ PyObject* d = PyModule_GetDict(m);
++ if (d == NULL)
++ return m;
++
++ PyDict_SetItemString(d, "PRIV_ON", PyLong_FromLong((long)PRIV_ON));
++ PyDict_SetItemString(d, "PRIV_OFF", PyLong_FromLong((long)PRIV_OFF));
++ PyDict_SetItemString(d, "PRIV_SET", PyLong_FromLong((long)PRIV_SET));
++
++ PyDict_SetItemString(d, "PRIV_PERMITTED", PyLong_FromLong((long)PRIV_PERMITTED));
++ PyDict_SetItemString(d, "PRIV_INHERITABLE", PyLong_FromLong((long)PRIV_INHERITABLE));
++ PyDict_SetItemString(d, "PRIV_LIMIT", PyLong_FromLong((long)PRIV_LIMIT));
++ PyDict_SetItemString(d, "PRIV_EFFECTIVE", PyLong_FromLong((long)PRIV_EFFECTIVE));
++
++ return m;
++}
+diff --git Python-2.6.4/Modules/pyrbac.c Python-2.6.4/Modules/pyrbac.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/pyrbac.c
[email protected]@ -0,0 +1,82 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * RBAC Bindings for Python
++ */
++
++#include <Python.h>
++#include "pyrbac.h"
++
++static PyMethodDef module_methods[] = {NULL};
++static char pyrbac__doc__[];
++
++PyDoc_STRVAR(pyrbac__doc__, "provides access to some objects \
++for interaction with the Solaris Role-Based Access Control \
++framework.\n\nDynamic objects:\n\
++userattr -- for interacting with user_attr(4)\n\
++authattr -- for interacting with auth_attr(4)\n\
++execattr -- for interacting with exec_attr(4)\n");
++
++#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
++#define PyMODINIT_FUNC void
++#endif
++PyMODINIT_FUNC
++PyInit_rbac (void) {
++ PyObject* m;
++
++ if (PyType_Ready(&AuthattrType) < 0 ||
++ PyType_Ready(&ExecattrType) < 0 ||
++ PyType_Ready(&UserattrType) < 0 )
++ return NULL;
++
++ static struct PyModuleDef moduledef = {
++ PyModuleDef_HEAD_INIT,
++ "rbac",
++ pyrbac__doc__,
++ -1,
++ module_methods,
++ NULL,
++ NULL,
++ NULL,
++ NULL,
++ };
++
++ m = PyModule_Create(&moduledef);
++ if ( m == NULL )
++ return NULL;
++
++ Py_INCREF(&AuthattrType);
++ PyModule_AddObject(m, "authattr", (PyObject*)&AuthattrType);
++
++ Py_INCREF(&ExecattrType);
++ PyModule_AddObject(m, "execattr", (PyObject*)&ExecattrType);
++
++ Py_INCREF(&UserattrType);
++ PyModule_AddObject(m, "userattr", (PyObject*)&UserattrType);
++
++ return m;
++
++}
+diff --git Python-2.6.4/Modules/pyrbac.h Python-2.6.4/Modules/pyrbac.h
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/pyrbac.h
[email protected]@ -0,0 +1,45 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * RBAC bindings for python
++ */
++#ifndef PYRBAC_H
++#define PYRBAC_H
++
++#include <secdb.h>
++
++
++#define PYRBAC_USER_MODE 1
++#define PYRBAC_PROF_MODE 2
++#define PYRBAC_ATTR_MODE 3
++#define PYRBAC_NAM_MODE 4
++#define PYRBAC_UID_MODE 5
++
++PyTypeObject AuthattrType;
++PyTypeObject ExecattrType;
++PyTypeObject UserattrType;
++
++#endif
+diff --git Python-2.6.4/Modules/userattr.c Python-2.6.4/Modules/userattr.c
+new file mode 100644
+--- /dev/null
++++ Python-2.6.4/Modules/userattr.c
[email protected]@ -0,0 +1,308 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ */
++
++/*
++ * RBAC Bindings for Python - user_attr functions
++ */
++
++#include <stdio.h>
++#include <user_attr.h>
++#include "Python.h"
++#include "pyrbac.h"
++
++static PyObject*
++pyrbac_setuserattr(PyObject* self, PyObject* args) {
++ setuserattr();
++ return Py_None;
++}
++
++static PyObject*
++pyrbac_enduserattr(PyObject* self, PyObject* args) {
++ enduserattr();
++ return Py_None;
++}
++
++PyObject*
++pyrbac_getuseruidnamattr(PyObject* self, void* arg, int mode, char* filename) {
++
++ userattr_t *ret_userattr;
++
++ if (mode == PYRBAC_ATTR_MODE) {
++ if (filename != NULL) {
++ FILE* file = fopen(filename, "r");
++ if (file == NULL)
++ return NULL;
++ ret_userattr = fgetuserattr(file);
++ if (fclose(file))
++ return NULL;
++ }
++ else
++ ret_userattr = getuserattr();
++ }
++ else if (mode == PYRBAC_NAM_MODE)
++ ret_userattr = getusernam((char*) arg);
++ else if (mode == PYRBAC_UID_MODE)
++ ret_userattr = getuseruid(*((uid_t*) arg));
++
++ if (ret_userattr == NULL)
++ return Py_None;
++
++ PyObject* entry = PyTuple_New(5);
++ if (entry == NULL) {
++ free_userattr(ret_userattr);
++ return NULL;
++ }
++
++ PyObject* kv_data = PyDict_New();
++
++ if(ret_userattr->attr != NULL) {
++ int len;
++ for(len = 0; len < ret_userattr->attr->length; len++) {
++ kv_t current = ret_userattr->attr->data[len];
++
++ PyObject* set = PyList_New(NULL);
++ char* saveptr;
++ char* item = strtok_r(current.value, ",", &saveptr);
++ PyList_Append(set, PyBytes_FromString(item));
++
++ while((item = strtok_r(NULL, ",", &saveptr)) != NULL) {
++ if(PyList_Append(set, PyBytes_FromString(item)) != 0) {
++ Py_XDECREF(set);
++ Py_XDECREF(kv_data);
++ free_userattr(ret_userattr);
++ return NULL;
++ }
++ }
++ if(PyDict_SetItemString(kv_data, current.key, set)) {
++ free_userattr(ret_userattr);
++ return NULL;
++ }
++ }
++ }
++ entry = Py_BuildValue("{s:s,s:s,s:s,s:s,s:O}",
++ "name", ret_userattr->name,
++ "qualifier", ret_userattr->qualifier,
++ "res1", ret_userattr->res1,
++ "res2", ret_userattr->res2,
++ "attributes", kv_data);
++
++ free_userattr(ret_userattr);
++
++ return entry;
++}
++
++
++static PyObject*
++pyrbac_getuserattr(PyObject* self, PyObject* args) {
++ return(pyrbac_getuseruidnamattr(self, (void*) NULL, PYRBAC_ATTR_MODE, NULL));
++}
++
++static PyObject*
++pyrbac_fgetuserattr(PyObject* self, PyObject* args) {
++ char* filename = NULL;
++ if(!PyArg_ParseTuple(args, "s:fgetuserattr", &filename))
++ return NULL;
++ return(pyrbac_getuseruidnamattr(self, NULL, PYRBAC_ATTR_MODE, filename));
++}
++
++static PyObject*
++pyrbac_getusernam(PyObject* self, PyObject* args) {
++ char* name = NULL;
++ if(!PyArg_ParseTuple(args, "s:getusernam", &name))
++ return NULL;
++ return(pyrbac_getuseruidnamattr(self, (void*) name, PYRBAC_NAM_MODE, NULL));
++}
++
++static PyObject*
++pyrbac_getuseruid(PyObject* self, PyObject* args) {
++ uid_t uid;
++ if(!PyArg_ParseTuple(args, "i:getuseruid", &uid))
++ return NULL;
++ return(pyrbac_getuseruidnamattr(self, (void*) &uid, PYRBAC_UID_MODE, NULL));
++}
++
++static PyObject*
++pyrbac_userattr_next(PyObject* self, PyObject* args) {
++ PyObject* retval = pyrbac_getuserattr(self, args);
++ if( retval == Py_None ) {
++ setuserattr();
++ return NULL;
++ }
++ return retval;
++}
++static PyObject*
++pyrbac_userattr__iter__(PyObject* self, PyObject* args) {
++ return self;
++}
++
++typedef struct {
++ PyObject_HEAD
++} Userattr;
++
++static void
++Userattr_dealloc(Userattr* self) {
++ enduserattr();
++ Py_TYPE(self)->tp_free((PyObject*) self);
++}
++
++static PyObject*
++Userattr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
++ Userattr *self;
++ self = (Userattr*)type->tp_alloc(type, 0);
++
++ return ((PyObject *) self);
++}
++
++static int
++Userattr_init(Userattr* self, PyObject *args, PyObject *kwargs) {
++ setuserattr();
++ return 0;
++}
++
++static char pyrbac_userattr__doc__[];
++PyDoc_STRVAR(pyrbac_userattr__doc__, "provides functions for \
++interacting with the extended user attributes database. May be iterated over \
++to enumerate user_attr(4) entries\n\n\
++Methods provided:\n\
++setuserattr\n\
++enduserattr\n\
++getuserattr\n\
++fgetuserattr\n\
++getusernam\n\
++getuseruid");
++
++static char pyrbac_setuserattr__doc__[];
++static char pyrbac_enduserattr__doc__[];
++static char pyrbac_getuserattr__doc__[];
++static char pyrbac_getusernam__doc__[];
++static char pyrbac_getuseruid__doc__[];
++
++PyDoc_STRVAR(pyrbac_setuserattr__doc__, "\"rewinds\" the user_attr functions \
++to the first entry in the db. Called automatically by the constructor.\n\
++\tArguments: None\n\
++\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_enduserattr__doc__, "closes the user_attr database, \
++cleans up storage. called automatically by the destructor\n\
++\tArguments: None\n\
++\tReturns: None");
++
++PyDoc_STRVAR(pyrbac_getuserattr__doc__, "Return a single user_attr entry\n \
++\tArguments: None\n\
++\tReturns: a dict representation of a userattr_t struct:\n\
++\t\t\"name\": username\n\
++\t\t\"qualifier\": reserved\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value"
++);
++
++PyDoc_STRVAR(pyrbac_fgetuserattr__doc__, "Return a single user_attr entry \
++from a file, bypassing nsswitch.conf\n\
++\tArguments: \'filename\'\n\
++\tReturns: a dict representation of a userattr_t struct:\n\
++\t\t\"name\": username\n\
++\t\t\"qualifier\": reserved\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value");
++
++PyDoc_STRVAR(pyrbac_getusernam__doc__, "Searches for a user_attr entry with a \
++given user name\n\
++\tArgument: \'username\'\n\
++\tReturns: a dict representation of a userattr_t struct:\n\
++\t\t\"name\": username\n\
++\t\t\"qualifier\": reserved\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value");
++
++PyDoc_STRVAR(pyrbac_getuseruid__doc__, "Searches for a user_attr entry with a \
++given uid\n\
++\tArgument: uid\n\
++\tReturns: a dict representation of a userattr_t struct:\n\
++\t\t\"name\": username\n\
++\t\t\"qualifier\": reserved\n\
++\t\t\"res1\": reserved\n\
++\t\t\"res2\": reserved\n\
++\t\t\"attributes\": A Python dict keyed by attribute & valued as either a list \
++or a string depending on value");
++
++static PyMethodDef Userattr_methods[] = {
++ {"setuserattr", pyrbac_setuserattr, METH_NOARGS, pyrbac_setuserattr__doc__},
++ {"enduserattr", pyrbac_enduserattr, METH_NOARGS, pyrbac_enduserattr__doc__},
++ {"getuserattr", pyrbac_getuserattr, METH_NOARGS, pyrbac_getuserattr__doc__},
++ {"fgetuserattr", pyrbac_fgetuserattr, METH_VARARGS, pyrbac_fgetuserattr__doc__},
++ {"getusernam", pyrbac_getusernam, METH_VARARGS, pyrbac_getusernam__doc__},
++ {"getuseruid", pyrbac_getuseruid, METH_VARARGS, pyrbac_getuseruid__doc__},
++ {NULL, NULL}
++};
++
++PyTypeObject UserattrType = {
++ PyVarObject_HEAD_INIT(NULL, 0)
++ "rbac.userattr", /*tp_name*/
++ sizeof(Userattr), /*tp_basicsize*/
++ 0, /*tp_itemsize*/
++ (destructor)Userattr_dealloc, /*tp_dealloc*/
++ 0, /*tp_print*/
++ 0, /*tp_getattr*/
++ 0, /*tp_setattr*/
++ 0, /*tp_reserved*/
++ 0, /*tp_repr*/
++ 0, /*tp_as_number*/
++ 0, /*tp_as_sequence*/
++ 0, /*tp_as_mapping*/
++ 0, /*tp_hash */
++ 0, /*tp_call*/
++ 0, /*tp_str*/
++ 0, /*tp_getattro*/
++ 0, /*tp_setattro*/
++ 0, /*tp_as_buffer*/
++ Py_TPFLAGS_DEFAULT |
++ Py_TPFLAGS_BASETYPE, /*tp_flags*/
++ pyrbac_userattr__doc__, /* tp_doc */
++ 0, /* tp_traverse */
++ 0, /* tp_clear */
++ 0, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ pyrbac_userattr__iter__, /* tp_iter */
++ pyrbac_userattr_next, /* tp_iternext */
++ Userattr_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ (initproc)Userattr_init, /* tp_init */
++ 0, /* tp_alloc */
++ Userattr_new, /* tp_new */
++ 0, /* tp_free */
++ 0, /* tp_is_gc */
++};
+--- Python-3.5.0a4/setup.py.~5~ 2015-04-20 13:30:08.410768276 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:30:08.438983714 -0700
[email protected]@ -1545,6 +1545,22 @@
+ exts.append( Extension('dlpi', ['dlpimodule.c'],
+ libraries = ['dlpi']) )
+
++ # privileges module (Solaris)
++ priv_inc = find_file('priv.h', [], inc_dirs)
++ if priv_inc is not None:
++ exts.append( Extension('privileges', ['privileges.c']))
++
++ # rbac module (Solaris)
++ secdb_inc = find_file('secdb.h', [], inc_dirs)
++ aa_inc = find_file('auth_attr.h', [], inc_dirs)
++ ea_inc = find_file('exec_attr.h', [], inc_dirs)
++ ua_inc = find_file('user_attr.h', [], inc_dirs)
++ if secdb_inc is not None and aa_inc is not None and \
++ ea_inc is not None and ua_inc is not None:
++ exts.append( Extension('rbac', ['pyrbac.c', 'authattr.c', \
++ 'execattr.c', 'userattr.c'],
++ libraries = ['nsl', 'socket', 'secdb']) )
++
+ # Thomas Heller's _ctypes module
+ self.detect_ctypes(inc_dirs, lib_dirs)
+
+--- /dev/null 2011-02-12 03:13:57.000000000 -0600
++++ Python-3.4.0/Lib/test/privrbactest.py 2011-01-20 13:52:42.862305331 -0600
[email protected]@ -0,0 +1,289 @@
++#!/usr/bin/python3.5
++#
++# CDDL HEADER START
++#
++# The contents of this file are subject to the terms of the
++# Common Development and Distribution License (the "License").
++# You may not use this file except in compliance with the License.
++#
++# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++# or http://www.opensolaris.org/os/licensing.
++# See the License for the specific language governing permissions
++# and limitations under the License.
++#
++# When distributing Covered Code, include this CDDL HEADER in each
++# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++# If applicable, add the following below this CDDL HEADER, with the
++# fields enclosed by brackets "[]" replaced with your own identifying
++# information: Portions Copyright [yyyy] [name of copyright owner]
++#
++# CDDL HEADER END
++#
++
++# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++
++import privileges
++import rbac
++import os
++import sys
++import tempfile
++
++# privileges tests
++
++def test_setppriv():
++ amchild = os.fork()
++ if amchild == 0:
++ if privileges.setppriv(privileges.PRIV_OFF, privileges.PRIV_EFFECTIVE,
++ ['proc_fork']):
++ try:
++ os.fork()
++ sys.exit(1)
++ except OSError as e:
++ sys.exit(0)
++
++ child = os.wait()
++ if child[1] is not 0:
++ print("setppriv. Bad exit status from pid %i\n" % child[0])
++ return False
++ return True
++
++def test_getppriv():
++ if 'proc_fork' in privileges.getppriv(privileges.PRIV_LIMIT):
++ return True
++ print("getppriv or PRIV_PROC_FORK not in PRIV_LIMIT.\n")
++ return False
++
++def test_priv_ineffect():
++ if privileges.priv_ineffect('proc_fork'):
++ return True
++ print("priv_ineffect or PRIV_PROC_FORK not in effect\n")
++ return False
++
++# authattr tests
++
++def test_chkauthattr():
++ try:
++ a = rbac.authattr()
++ except Exception as e:
++ print("Could not instantiate authattr object: %s\n" % e)
++ return False
++ try:
++ res = a.chkauthattr('solaris.*', 'root')
++ except Exception as e:
++ print("chkauthattr failed: %s\n" % e)
++ return False
++ if not res:
++ print("chkauthattr failed or \'root\' lacks \'solaris.*\'\n")
++ return False
++ return True
++
++def test_getauthattr():
++ try:
++ a = rbac.authattr()
++ except Exception as e:
++ print("Could not instantiate authattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getauthattr()
++ except Exception as e:
++ print("getauthattr failed: %s\n" % e)
++ return False
++ if not 'name' in list(res.keys()):
++ print("getauthattr failed\n")
++ return False
++ return True
++
++def test_getauthnam():
++ try:
++ a = rbac.authattr()
++ except Exception as e:
++ print("Could not instantiate authattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getauthnam('solaris.')
++ except Exception as e:
++ print("getauthnam failed: %s\n" % e)
++ return False
++ if not res:
++ print("getauthnam failed or \'solaris.\' not in auth_attr(4)\n")
++ return False
++ return True
++
++def test_authattr_iter():
++ try:
++ a = rbac.authattr()
++ except Exception as e:
++ print("Could not instantiate authattr object: %s\n" % e)
++ return False
++ res = next(a)
++ if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
++ print("authattr object is not an iterable\n")
++ return False
++ return True
++
++# execattr tests
++
++def test_getexecattr():
++ try:
++ a = rbac.execattr()
++ except Exception as e:
++ print("Could not instantiate execattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getexecattr()
++ except Exception as e:
++ print("getexecattr failed: %s\n" % e)
++ return False
++ if not 'name' in list(res.keys()):
++ print("getexecattr failed\n")
++ return False
++ return True
++
++def test_getexecuser():
++ try:
++ a = rbac.execattr()
++ except Exception as e:
++ print("Could not instantiate execattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getexecuser("root", "act", "*;*;*;*;*")
++ except Exception as e:
++ print("getexecuser failed: %s\n" % e)
++ return False
++ if not res:
++ print("getexecuser failed or \'root\' not assigned to \'act\', " \
++ "\'*;*;*;*;*\' \n")
++ return False
++ return True
++
++
++def test_getexecprof():
++ try:
++ a = rbac.execattr()
++ except Exception as e:
++ print("Could not instantiate execattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getexecprof("All", "cmd", "*")
++ except Exception as e:
++ print("getexecprof failed: %s\n" % e)
++ return False
++ if not res:
++ print("getexecprof failed or \'All\' not granted \'cmd\' : \'*\'\n")
++ return False
++ return True
++
++def test_execattr_iter():
++ try:
++ a = rbac.execattr()
++ except Exception as e:
++ print("Could not instantiate execattr object: %s\n" % e)
++ return False
++ res = next(a)
++ if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
++ print("execattr object is not an iterable\n")
++ return False
++ return True
++
++# userattr tests
++
++def test_getuserattr():
++ try:
++ a = rbac.userattr()
++ except Exception as e:
++ print("Could not instantiate userattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getuserattr()
++ except Exception as e:
++ print("getuserattr failed: %s\n" % e)
++ return False
++ if not 'name' in list(res.keys()):
++ print("getuserattr failed\n")
++ return False
++ return True
++
++def test_fgetuserattr():
++ temp = tempfile.NamedTemporaryFile()
++ temp.write("user::::profiles=Software Installation;roles=foo;"\
++ "auths=solaris.foo.bar")
++ temp.seek(0)
++ try:
++ a = rbac.userattr()
++ except Exception as e:
++ print("Could not instantiate userattr object: %s\n" % e)
++ return False
++ try:
++ res = a.fgetuserattr(temp.name)
++ temp.close()
++ except Exception as e:
++ print("fgetuserattr failed: %s\n" % e)
++ temp.close()
++ return False
++ if not 'name' in list(res.keys()):
++ print("fgetuserattr failed\n")
++ return False
++ return True
++
++def test_getuseruid():
++ try:
++ a = rbac.userattr()
++ except Exception as e:
++ print("Could not instantiate userattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getuseruid(0)
++ except Exception as e:
++ print("getusernam failed: %s\n" % e)
++ return False
++ if not 'name' in res:
++ print("getusernam failed or no uid 0\n")
++ return False
++ return True
++
++def test_getusernam():
++ try:
++ a = rbac.userattr()
++ except Exception as e:
++ print("Could not instantiate userattr object: %s\n" % e)
++ return False
++ try:
++ res = a.getusernam('root')
++ except Exception as e:
++ print("getusernam failed: %s\n" % e)
++ return False
++ if not 'name' in res:
++ print("getusernam failed or no \'root\' user\n")
++ return False
++ return True
++
++def test_userattr_iter():
++ try:
++ a = rbac.userattr()
++ except Exception as e:
++ print("Could not instantiate userattr object: %s\n" % e)
++ return False
++ res = next(a)
++ if not 'name' in list(res.keys()) or type(a) != type(a.__iter__()):
++ print("userattr object is not an iterable\n")
++ return False
++ return True
++
++if not test_setppriv() or not test_getppriv() or not test_priv_ineffect():
++ print("*** Failures detected in privileges module\n")
++ sys.exit(1)
++
++if not test_getauthattr() or not test_chkauthattr() or not test_getauthnam() \
++ or not test_authattr_iter:
++ print("*** Failures detected in rbac.authattr\n")
++ sys.exit(1)
++
++if not test_getexecattr() or not test_getexecuser() or not test_getexecprof() \
++ or not test_execattr_iter():
++ print("*** Failures detected in rbac.execattr\n")
++ sys.exit(1)
++
++if not test_getuserattr() or not test_fgetuserattr() or not test_getusernam()\
++ or not test_getuseruid() or not test_userattr_iter():
++ print("*** Failures detected in rbac.userattr\n")
++ sys.exit(1)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/11-closerange.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,42 @@
+This patch uses fdwalk(3c) to close file descriptors; as that function is not
+widely implemented, this is unsuitable for upstream.
+
+--- Python-3.5.0rc2/Modules/posixmodule.c.~1~ 2015-08-25 10:19:14.000000000 -0700
++++ Python-3.5.0rc2/Modules/posixmodule.c 2015-09-02 12:31:54.885953202 -0700
[email protected]@ -7781,6 +7781,19 @@
+ Py_RETURN_NONE;
+ }
+
++static int
++close_func(void *lohi, int fd)
++{
++ int lo = ((int *)lohi)[0];
++ int hi = ((int *)lohi)[1];
++
++ if (fd >= hi)
++ return (1);
++ else if (fd >= lo)
++ close(fd);
++
++ return (0);
++}
+
+ /*[clinic input]
+ os.closerange
[email protected]@ -7797,11 +7810,13 @@
+ /*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
+ {
+ int i;
++ int lohi[2];
++
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+- for (i = fd_low; i < fd_high; i++)
+- if (_PyVerify_fd(i))
+- close(i);
++ lohi[0] = fd_low;
++ lohi[1] = fd_high;
++ fdwalk(close_func, lohi);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ Py_RETURN_NONE;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/12-py_db.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,867 @@
+This patch adds Python debugger support. It may be contributed upstream at
+some point, but the suitability (or lack thereof) has not yet been determined.
+
+--- Python-3.5.0rc2/Makefile.pre.in.~3~ 2015-09-02 12:32:56.683992213 -0700
++++ Python-3.5.0rc2/Makefile.pre.in 2015-09-02 12:32:56.824907825 -0700
[email protected]@ -482,7 +482,7 @@
+
+ # Default target
+ all: build_all
+-build_all: $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Programs/_testembed python-config
++build_all: $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Programs/_testembed python-config build-py_db
+
+ # Compile a binary with gcc profile guided optimization.
+ profile-opt:
[email protected]@ -685,6 +685,15 @@
+ @mv config.c Modules
+ @echo "The Makefile was updated, you may need to re-run make."
+
++SHLIB_FLAGS = -shared -fpic
++
++libpython$(LDVERSION)_db.so.1.0: $(srcdir)/py_db/libpython35_db.c
++ $(CC) -o [email protected] $(CFLAGS) $(PY_CPPFLAGS) $(CPPFLAGS) $(SHLIB_FLAGS) $<
++
++build-py_db: libpython$(LDVERSION)_db.so.1.0
++
++install-py_db: libpython$(LDVERSION)_db.so.1.0
++ $(INSTALL_SHARED) libpython$(LDVERSION)_db.so.1.0 $(DESTDIR)$(LIBDIR)
+
+ Modules/Setup: $(srcdir)/Modules/Setup.dist
+ @if test -f Modules/Setup; then \
[email protected]@ -1062,7 +1071,7 @@
+ $(TESTRUNNER) $(QUICKTESTOPTS)
+
+
+-install: @[email protected] commoninstall bininstall maninstall @[email protected]
++install: @[email protected] commoninstall bininstall maninstall install-py_db @[email protected]
+ if test "x$(ENSUREPIP)" != "xno" ; then \
+ case $(ENSUREPIP) in \
+ upgrade) ensurepip="--upgrade" ;; \
+--- /dev/null 2015-05-14 14:46:26.000000000 -0700
++++ Python-3.5.0/py_db/libpython35_db.c 2015-05-14 14:45:15.723529281 -0700
[email protected]@ -0,0 +1,583 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++/*
++ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <gelf.h>
++
++#include <Python.h>
++#include <frameobject.h>
++
++#include "libpython35_db.h"
++
++struct pydb_agent {
++ struct ps_prochandle *pdb_ph;
++ int pdb_vers;
++ int pdb_is_64bit;
++ int pdb_datamodel;
++};
++
++typedef uintptr_t (*pdi_next_cb_t)(pydb_iter_t *);
++
++struct pydb_iter {
++ struct ps_prochandle *pdi_ph;
++ uintptr_t pdi_current;
++ pdi_next_cb_t pdi_nextf;
++};
++
++#define LIBPYTHON "libpython3.5m.so"
++
++#define MIN(x, y) (((x) < (y)) ? (x) : (y))
++
++/* Generic interface to helper functions */
++static ssize_t pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr,
++ unsigned char *buf, size_t buf_len);
++static int pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
++ int lastinst);
++static int pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
++ size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
++
++/* datamodel specific implementation of helper functions */
++static ssize_t pydb_strobj_readdata_native(pydb_agent_t *py, uintptr_t addr,
++ unsigned char *buf, size_t buf_len);
++static int pydb_frameinfo_native(pydb_agent_t *py, uintptr_t addr, char *funcnm,
++ size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno);
++
++static ssize_t pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
++ size_t len);
++
++/* Iterator function next routines. Plugable, configured by iterator init */
++static uintptr_t pydb_frame_iter_next(pydb_iter_t *iter);
++static uintptr_t pydb_interp_iter_next(pydb_iter_t *iter);
++static uintptr_t pydb_thread_iter_next(pydb_iter_t *iter);
++
++static const char *strbasename(const char *s);
++
++static const char *
++strbasename(const char *s)
++{
++ const char *p = strrchr(s, '/');
++
++ if (p == NULL)
++ return (s);
++
++ return (++p);
++}
++
++/* Agent creation / destruction routines */
++
++pydb_agent_t *
++pydb_agent_create(struct ps_prochandle *P, int vers)
++{
++ pydb_agent_t *py;
++ int datamodel;
++
++ if (vers != PYDB_VERSION) {
++ errno = ENOTSUP;
++ return (NULL);
++ }
++
++ if (ps_pdmodel(P, &datamodel) != PS_OK) {
++ return (NULL);
++ }
++
++ py = (pydb_agent_t *)malloc(sizeof (pydb_agent_t));
++ if (py == NULL) {
++ return (NULL);
++ }
++
++ py->pdb_ph = P;
++ py->pdb_vers = vers;
++ py->pdb_datamodel = datamodel;
++ py->pdb_is_64bit = 0;
++
++ return (py);
++}
++
++void
++pydb_agent_destroy(pydb_agent_t *py)
++{
++ if (py == NULL) {
++ return;
++ }
++
++ free(py);
++}
++
++/* Helper functions */
++static int
++pydb_getlno(pydb_agent_t *py, uintptr_t lnotab_addr, int firstline,
++ int lastinst)
++{
++ unsigned char lnotab[4096];
++ ssize_t lnotab_len;
++ int addr, line;
++ int i;
++
++ lnotab_len = pydb_strobj_readdata(py, lnotab_addr, lnotab,
++ sizeof (lnotab));
++ if (lnotab_len < 0) {
++ return (-1);
++ }
++
++ /*
++ * Python's line number algorithm is arcane. See here for details:
++ * http://svn.python.org/projects/python/trunk/Objects/lnotab_notes.txt
++ */
++
++ line = firstline;
++ for (addr = i = 0; i < lnotab_len; i += 2) {
++ if (addr + lnotab[i] > lastinst) {
++ break;
++ }
++ addr += lnotab[i];
++ line += lnotab[i + 1];
++ }
++
++ return (line);
++}
++
++static ssize_t
++pydb_asciiobj_readdata(pydb_agent_t *py, uintptr_t addr,
++ unsigned char *buf, size_t buf_len)
++{
++ PyASCIIObject sobj;
++ ssize_t obj_sz;
++ ssize_t read_sz;
++ psaddr_t asciiaddr;
++
++ /*
++ * PyASCIIObjects are a type of Unicode string. They are identified
++ * as follows:
++ * - sobj.state.compact == 1
++ * - sobj.state.ascii == 1
++ * - sobj.state.ready == 1
++ * The length of the string is stored in sobj.length. The string
++ * itself follows the PyASCIIObject.
++ */
++
++ if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyASCIIObject))
++ != PS_OK) {
++ return (-1);
++ }
++
++ if (!sobj.state.compact || !sobj.state.ascii || !sobj.state.ready) {
++ return (-1);
++ }
++
++ obj_sz = (ssize_t)sobj.length;
++
++ read_sz = MIN(obj_sz, (ssize_t)buf_len);
++ asciiaddr = (psaddr_t)(addr + sizeof (PyASCIIObject));
++
++ if (ps_pread(py->pdb_ph, asciiaddr, buf, (size_t)read_sz) != PS_OK) {
++ return (-1);
++ }
++
++ return (read_sz);
++}
++
++static ssize_t
++pydb_asciiobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
++ size_t buf_len)
++{
++ ssize_t read_sz;
++
++ read_sz = pydb_asciiobj_readdata(py, addr, (unsigned char *)buf,
++ buf_len);
++
++ if (read_sz >= 0) {
++ if (read_sz >= buf_len) {
++ read_sz = buf_len - 1;
++ }
++
++ buf[read_sz] = '\0';
++ }
++
++ return (read_sz);
++}
++
++static ssize_t
++pydb_strobj_readdata(pydb_agent_t *py, uintptr_t addr,
++ unsigned char *buf, size_t buf_len)
++{
++ PyBytesObject sobj;
++ ssize_t obj_sz;
++ ssize_t read_sz;
++ psaddr_t straddr;
++
++ /*
++ * PyBytesObject are variable size. The size of the PyBytesObject
++ * struct is fixed, and known at compile time; however, the size of the
++ * associated buffer is variable. The char[1] element at the end of the
++ * structure contains the string, and the ob_size of the PyBytesObject
++ * indicates how much extra space was allocated to contain the string
++ * buffer at the object's tail. Read in the fixed size portion of the
++ * object first, and then read the contents of the data buffer into the
++ * buffer passed by the caller.
++ */
++
++ if (ps_pread(py->pdb_ph, addr, &sobj, sizeof (PyBytesObject))
++ != PS_OK) {
++ return (-1);
++ }
++
++ /*
++ * If we want to emulate PyBytes_GET_SIZE() instead of just calling
++ * Py_SIZE() directly, we need to do a ps_pread() of Py_TYPE(&sobj).
++ * PyBytes_Check() will try to access the type structure, but the
++ * address is not in the debugger's address space.
++ */
++ obj_sz = (ssize_t)Py_SIZE(&sobj);
++
++ read_sz = MIN(obj_sz, (ssize_t)buf_len);
++ straddr = (psaddr_t)(addr + offsetof(PyBytesObject, ob_sval));
++
++ if (ps_pread(py->pdb_ph, straddr, buf, (size_t)read_sz) != PS_OK) {
++ return (-1);
++ }
++
++ return (read_sz);
++}
++
++/*
++ * Most Python PyBytesObject contain strings, as one would expect. However,
++ * due to some sleazy hackery in parts of the Python code, some string objects
++ * are used as buffers for binary data. In the general case,
++ * pydb_strobj_readstr() should be used to read strings out of string objects.
++ * It wraps pydb_strobj_readdata(), which should be used by callers only when
++ * trying to retrieve binary data. (This routine does some string cleanup).
++ */
++static ssize_t
++pydb_strobj_readstr(pydb_agent_t *py, uintptr_t addr, char *buf,
++ size_t buf_len)
++{
++ ssize_t read_sz;
++
++ read_sz = pydb_strobj_readdata(py, addr, (unsigned char *)buf, buf_len);
++
++ if (read_sz >= 0) {
++ if (read_sz >= buf_len) {
++ read_sz = buf_len - 1;
++ }
++
++ buf[read_sz] = '\0';
++ }
++
++ return (read_sz);
++}
++
++
++static int
++pydb_frameinfo(pydb_agent_t *py, uintptr_t addr, char *funcnm,
++ size_t funcnm_sz, char *filenm, size_t filenm_sz, int *lineno)
++{
++ PyFrameObject fo;
++ PyCodeObject co;
++ ssize_t rc;
++
++ if (ps_pread(py->pdb_ph, addr, &fo, sizeof (PyFrameObject))
++ != PS_OK) {
++ return (-1);
++ }
++
++ if (ps_pread(py->pdb_ph, (uintptr_t)fo.f_code, &co,
++ sizeof (PyCodeObject)) != PS_OK) {
++ return (-1);
++ }
++
++ rc = pydb_asciiobj_readstr(py, (uintptr_t)co.co_name, funcnm,
++ funcnm_sz);
++ if (rc < 0) {
++ return (-1);
++ }
++
++ rc = pydb_asciiobj_readstr(py, (uintptr_t)co.co_filename, filenm,
++ filenm_sz);
++ if (rc < 0) {
++ return (-1);
++ }
++
++ *lineno = pydb_getlno(py, (uintptr_t)co.co_lnotab, co.co_firstlineno,
++ fo.f_lasti);
++ if (*lineno < 0) {
++ return (-1);
++ }
++
++ return (0);
++}
++
++/* Functions that are part of the library's interface */
++
++/*
++ * Given the address of a PyFrameObject, and a buffer of a known size,
++ * fill the buffer with a description of the frame.
++ */
++int
++pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr, char *fbuf,
++ size_t bufsz, int verbose)
++{
++ char funcname[1024];
++ char filename[1024];
++ char *fn;
++ int lineno;
++ int length = (py->pdb_is_64bit ? 16 : 8);
++ int rc;
++
++ rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
++ filename, sizeof (filename), &lineno);
++ if (rc < 0) {
++ return (-1);
++ }
++
++ if (!verbose) {
++ fn = (char *)strbasename(filename);
++ } else {
++ fn = filename;
++ }
++
++ (void) snprintf(fbuf, bufsz, "%0.*lx %s:%d %s()\n", length,
++ frame_addr, fn, lineno, funcname);
++
++ return (0);
++}
++
++/*
++ * Return a description about a PyFrameObject, if the object is
++ * actually a PyFrameObject. In this case, the pc argument is checked
++ * to make sure that it came from a function that takes a PyFrameObject
++ * as its first (argv[0]) argument.
++ */
++int
++pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc, uintptr_t frame_addr,
++ char *fbuf, size_t bufsz)
++{
++ char funcname[1024];
++ char filename[1024];
++ int lineno;
++ int rc;
++ ps_sym_t psym;
++
++ /*
++ * If PC doesn't match PyEval_EvalFrameEx in either libpython
++ * or the executable, don't decode it.
++ */
++ if (ps_pglobal_sym(py->pdb_ph, LIBPYTHON, "PyEval_EvalFrameEx", &psym)
++ != PS_OK) {
++ return (-1);
++ }
++
++ /* If symbol found, ensure that PC falls within PyEval_EvalFrameEx. */
++ if (pc < psym.st_value || pc > psym.st_value + psym.st_size) {
++ return (-1);
++ }
++
++ rc = pydb_frameinfo(py, frame_addr, funcname, sizeof (funcname),
++ filename, sizeof (filename), &lineno);
++ if (rc < 0) {
++ return (-1);
++ }
++
++ (void) snprintf(fbuf, bufsz, "[ %s:%d (%s) ]\n", filename, lineno,
++ funcname);
++
++ return (0);
++}
++
++/*
++ * Walks the list of PyInterpreterState objects. If caller doesn't
++ * supply address of list, this method will look it up.
++ */
++pydb_iter_t *
++pydb_interp_iter_init(pydb_agent_t *py, uintptr_t addr)
++{
++ pydb_iter_t *itr;
++ uintptr_t i_addr;
++ int rc;
++
++ if (addr == 0) {
++ rc = ps_pglobal_lookup(py->pdb_ph, LIBPYTHON, "interp_head",
++ (psaddr_t *)&addr);
++ if (rc != PS_OK) {
++ return (NULL);
++ }
++ }
++
++ if (ps_pread(py->pdb_ph, (uintptr_t)addr, &i_addr, sizeof (uintptr_t))
++ != PS_OK) {
++ return (NULL);
++ }
++
++ itr = malloc(sizeof (pydb_iter_t));
++ if (itr == NULL) {
++ return (NULL);
++ }
++
++ itr->pdi_ph = py->pdb_ph;
++ itr->pdi_current = i_addr;
++ itr->pdi_nextf = pydb_interp_iter_next;
++
++ return (itr);
++}
++
++static uintptr_t
++pydb_interp_iter_next(pydb_iter_t *iter)
++{
++ PyInterpreterState st;
++ uintptr_t cur;
++
++ cur = iter->pdi_current;
++
++ if (cur == 0) {
++ return (cur);
++ }
++
++ if (ps_pread(iter->pdi_ph, cur, &st, sizeof (PyInterpreterState))
++ != PS_OK) {
++ iter->pdi_current = 0;
++ return (0);
++ }
++
++ iter->pdi_current = (uintptr_t)st.next;
++
++ return (cur);
++}
++
++/*
++ * Walk a list of Python PyFrameObjects. The addr argument must be
++ * the address of a valid PyThreadState object.
++ */
++pydb_iter_t *
++pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr)
++{
++ pydb_iter_t *itr;
++ PyThreadState ts;
++
++ if (ps_pread(py->pdb_ph, (uintptr_t)addr, &ts, sizeof (PyThreadState))
++ != PS_OK) {
++ return (NULL);
++ }
++
++ itr = malloc(sizeof (pydb_iter_t));
++ if (itr == NULL) {
++ return (NULL);
++ }
++
++ itr->pdi_ph = py->pdb_ph;
++ itr->pdi_current = (uintptr_t)ts.frame;
++ itr->pdi_nextf = pydb_frame_iter_next;
++
++ return (itr);
++}
++
++static uintptr_t
++pydb_frame_iter_next(pydb_iter_t *iter)
++{
++ PyFrameObject fo;
++ uintptr_t cur;
++
++ cur = iter->pdi_current;
++
++ if (cur == 0) {
++ return (cur);
++ }
++
++ if (ps_pread(iter->pdi_ph, cur, &fo, sizeof (PyFrameObject))
++ != PS_OK) {
++ iter->pdi_current = 0;
++ return (0);
++ }
++
++ iter->pdi_current = (uintptr_t)fo.f_back;
++
++ return (cur);
++}
++
++/*
++ * Walk a list of Python PyThreadState objects. The addr argument must be
++ * the address of a valid PyInterpreterState object.
++ */
++pydb_iter_t *
++pydb_thread_iter_init(pydb_agent_t *py, uintptr_t addr)
++{
++ pydb_iter_t *itr;
++ PyInterpreterState is;
++
++ if (ps_pread(py->pdb_ph, (uintptr_t)addr, &is,
++ sizeof (PyInterpreterState)) != PS_OK) {
++ return (NULL);
++ }
++
++ itr = malloc(sizeof (pydb_iter_t));
++ if (itr == NULL) {
++ return (NULL);
++ }
++
++ itr->pdi_ph = py->pdb_ph;
++ itr->pdi_current = (uintptr_t)is.tstate_head;
++ itr->pdi_nextf = pydb_thread_iter_next;
++
++ return (itr);
++}
++
++static uintptr_t
++pydb_thread_iter_next(pydb_iter_t *iter)
++{
++ PyThreadState ts;
++ uintptr_t cur;
++
++ cur = iter->pdi_current;
++
++ if (cur == 0) {
++ return (cur);
++ }
++
++ if (ps_pread(iter->pdi_ph, cur, &ts, sizeof (PyThreadState)) != PS_OK) {
++ iter->pdi_current = 0;
++ return (0);
++ }
++
++ iter->pdi_current = (uintptr_t)ts.next;
++
++ return (cur);
++}
++
++
++uintptr_t
++pydb_iter_next(pydb_iter_t *iter)
++{
++ return (iter->pdi_nextf(iter));
++}
++
++void
++pydb_iter_fini(pydb_iter_t *iter)
++{
++ if (iter == NULL) {
++ return;
++ }
++
++ free(iter);
++}
+--- /dev/null
++++ Python-3.5.0/py_db/libpython35_db.h
[email protected]@ -0,0 +1,73 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ */
++
++#ifndef _LIBPYTHON35_DB_H
++#define _LIBPYTHON35_DB_H
++
++#include <proc_service.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Agent is opaque to library's consumers. */
++typedef struct pydb_agent pydb_agent_t;
++
++/*
++ * Library's debug version is 1. Changes to interface should increase this
++ * number.
++ */
++#define PYDB_VERSION 1
++
++/* Agent creation/destruction routines */
++extern pydb_agent_t *pydb_agent_create(struct ps_prochandle *P, int vers);
++extern void pydb_agent_destroy(pydb_agent_t *py);
++
++/* Used by callers that know they are looking at a PyFrameObject */
++extern int pydb_get_frameinfo(pydb_agent_t *py, uintptr_t frame_addr,
++ char *fbuf, size_t bufsz, int verbose);
++
++/*
++ * Used by callers that don't know if they're looking at PyFrameObject.
++ * Checks PC for traceable functions.
++ */
++extern int pydb_pc_frameinfo(pydb_agent_t *py, uintptr_t pc,
++ uintptr_t frame_addr, char *fbuf, size_t bufsz);
++
++/* Iterator functions */
++typedef struct pydb_iter pydb_iter_t;
++
++extern pydb_iter_t *pydb_frame_iter_init(pydb_agent_t *py, uintptr_t addr);
++extern pydb_iter_t *pydb_interp_iter_init(pydb_agent_t *py,
++ uintptr_t addr);
++extern pydb_iter_t *pydb_thread_iter_init(pydb_agent_t *py,
++ uintptr_t addr);
++extern void pydb_iter_fini(pydb_iter_t *iter);
++extern uintptr_t pydb_iter_next(pydb_iter_t *iter);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _LIBPYTHON35_DB_H */
+--- /dev/null
++++ Python-3.5.0/py_db/libpython35_db_32.h
[email protected]@ -0,0 +1,121 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License (the "License").
++ * You may not use this file except in compliance with the License.
++ *
++ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++ * or http://www.opensolaris.org/os/licensing.
++ * See the License for the specific language governing permissions
++ * and limitations under the License.
++ *
++ * When distributing Covered Code, include this CDDL HEADER in each
++ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++ * If applicable, add the following below this CDDL HEADER, with the
++ * fields enclosed by brackets "[]" replaced with your own identifying
++ * information: Portions Copyright [yyyy] [name of copyright owner]
++ *
++ * CDDL HEADER END
++ */
++/*
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
++ */
++
++#ifndef _LIBPYTHON35_DB_32_H
++#define _LIBPYTHON35_DB_32_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#include <sys/types.h>
++
++/*
++ * Define 32-bit Python data structures for use by the 64-bit debugger. This
++ * is so that a 64-bit debugger may properly examine a 32-bit process.
++ *
++ * In many cases, the debug library is only concerned with a few fields in the
++ * Python structure. In that case, the other ancillary fields are elided.
++ */
++
++typedef uint32_t uintptr32_t;
++typedef int32_t Py_ssize32_t;
++
++typedef struct _is32 {
++ uintptr32_t next;
++ uintptr32_t tstate_head;
++} PyInterpreterState32;
++
++typedef struct _ts32 {
++ uintptr32_t next;
++ uintptr32_t interp;
++ uintptr32_t frame;
++} PyThreadState32;
++
++#define PyObject_HEAD32 \
++ Py_ssize32_t ob_refcnt; \
++ uintptr32_t ob_type;
++
++#define PyObject_VAR_HEAD32 \
++ PyObject_HEAD32 \
++ Py_ssize32_t ob_size;
++
++typedef struct {
++ PyObject_HEAD32
++} PyObject32;
++
++typedef struct {
++ PyObject_VAR_HEAD32
++} PyVarObject32;
++
++typedef struct {
++ PyObject_VAR_HEAD32
++ int32_t ob_shash;
++ int ob_sstate;
++ char ob_sval[1];
++} PyBytesObject32;
++
++#define Py_SIZE32(ob) (((PyVarObject32*)(ob))->ob_size)
++#define PyString_GET_SIZE32(op) Py_SIZE32(op)
++#define PyString_AS_STRING32(op) (((PyBytesObject32 *)(op))->ob_sval)
++
++typedef struct {
++ PyObject_VAR_HEAD32
++ uintptr32_t f_back;
++ uintptr32_t f_code;
++ uintptr32_t f_builtins;
++ uintptr32_t f_globals;
++ uintptr32_t f_locals;
++ uintptr32_t f_valuestack;
++ uintptr32_t f_stacktop;
++ uintptr32_t f_trace;
++ uintptr32_t f_exc_typpe, f_exc_value, f_exc_traceback;
++ uintptr32_t f_tstate;
++ int f_lasti;
++ int f_lineno;
++} PyFrameObject32;
++
++typedef struct {
++ PyObject_HEAD32
++ int co_argcount;
++ int co_nlocals;
++ int co_stacksize;
++ int co_flags;
++ uintptr32_t co_code;
++ uintptr32_t co_consts;
++ uintptr32_t co_names;
++ uintptr32_t co_varnames;
++ uintptr32_t co_freevars;
++ uintptr32_t co_cellvars;
++ uintptr32_t co_filename;
++ uintptr32_t co_name;
++ int co_firstlineno;
++ uintptr32_t co_lnotab;
++} PyCodeObject32;
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _LIBPYTHON35_DB_32_H */
+--- /dev/null
++++ Python-3.5.0/py_db/mapfile-vers
[email protected]@ -0,0 +1,39 @@
++#
++# CDDL HEADER START
++#
++# The contents of this file are subject to the terms of the
++# Common Development and Distribution License (the "License").
++# You may not use this file except in compliance with the License.
++#
++# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
++# or http://www.opensolaris.org/os/licensing.
++# See the License for the specific language governing permissions
++# and limitations under the License.
++#
++# When distributing Covered Code, include this CDDL HEADER in each
++# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
++# If applicable, add the following below this CDDL HEADER, with the
++# fields enclosed by brackets "[]" replaced with your own identifying
++# information: Portions Copyright [yyyy] [name of copyright owner]
++#
++# CDDL HEADER END
++#
++
++#
++# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++#
++
++SUNWprivate_1.1 {
++ global:
++ pydb_agent_create;
++ pydb_agent_destroy;
++ pydb_frame_iter_init;
++ pydb_get_frameinfo;
++ pydb_pc_frameinfo;
++ pydb_interp_iter_init;
++ pydb_thread_iter_init;
++ pydb_iter_fini;
++ pydb_iter_next;
++ local:
++ *;
++};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/13-get_wch.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,52 @@
+This patch adds wget_wch support to the curses module. It may be contributed
+upstream at some point, but the suitability (or lack thereof) has not yet
+been determined.
+
+--- Python-3.5.0a4/Modules/_cursesmodule.c.~1~ 2015-04-20 00:37:52.000000000 -0700
++++ Python-3.5.0a4/Modules/_cursesmodule.c 2015-04-20 13:48:38.959560525 -0700
[email protected]@ -1124,6 +1124,37 @@
+ }
+
+ static PyObject *
++PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args)
++{
++ int x, y;
++ int ct;
++ wint_t rtn;
++
++ switch (PyTuple_Size(args)) {
++ case 0:
++ Py_BEGIN_ALLOW_THREADS
++ ct = wget_wch(self->win,&rtn);
++ Py_END_ALLOW_THREADS
++ break;
++ case 2:
++ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
++ return NULL;
++ Py_BEGIN_ALLOW_THREADS
++ ct = mvwget_wch(self->win,y,x,&rtn);
++ Py_END_ALLOW_THREADS
++ break;
++ default:
++ PyErr_SetString(PyExc_TypeError, "get_wch requires 0 or 2 arguments");
++ return NULL;
++ }
++ if (ct == ERR) {
++ PyErr_SetString(PyCursesError, "get_wch failed");
++ return NULL;
++ }
++ return PyLong_FromLong((long)rtn);
++}
++
++static PyObject *
+ PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
+ {
+ int x, y;
[email protected]@ -1996,6 +2027,7 @@
+ {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
+ {"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
+ {"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
++ {"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS},
+ {"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
+ #ifdef HAVE_NCURSESW
+ {"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/14-ossaudiodev.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,61 @@
+This patch is needed to make Python understand it can build the OSS plugin.
+Some OSS ioctls are not supported on Solaris, so they are ifdef'd out. As
+the patch is Solaris-specific, it is not suitable for upstream.
+
+--- Python-3.5.0a4/setup.py.~6~ 2015-04-20 13:49:47.441303130 -0700
++++ Python-3.5.0a4/setup.py 2015-04-20 13:49:47.506430752 -0700
[email protected]@ -1616,7 +1616,7 @@
+ # End multiprocessing
+
+ # Platform-specific libraries
+- if host_platform.startswith(('linux', 'freebsd', 'gnukfreebsd')):
++ if host_platform.startswith(('sunos5', 'linux', 'freebsd', 'gnukfreebsd')):
+ exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
+ else:
+ missing.append('ossaudiodev')
+--- Python-3.4.0/Modules/ossaudiodev.c.~1~ 2014-03-16 19:31:31.000000000 -0700
++++ Python-3.4.0/Modules/ossaudiodev.c 2014-03-17 13:48:16.395254733 -0700
[email protected]@ -1211,6 +1211,7 @@
+ _EXPORT_INT(m, SOUND_MIXER_MONITOR);
+ #endif
+
++#ifndef __sun
+ /* Expose all the ioctl numbers for masochists who like to do this
+ stuff directly. */
+ _EXPORT_INT(m, SNDCTL_COPR_HALT);
[email protected]@ -1223,6 +1224,7 @@
+ _EXPORT_INT(m, SNDCTL_COPR_SENDMSG);
+ _EXPORT_INT(m, SNDCTL_COPR_WCODE);
+ _EXPORT_INT(m, SNDCTL_COPR_WDATA);
++#endif
+ #ifdef SNDCTL_DSP_BIND_CHANNEL
+ _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL);
+ #endif
[email protected]@ -1244,8 +1246,12 @@
+ _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF);
+ #endif
+ _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER);
++#ifdef SNDCTL_DSP_MAPINBUF
+ _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF);
++#endif
++#ifdef SNDCTL_DSP_MAPOUTBUF
+ _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF);
++#endif
+ _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK);
+ _EXPORT_INT(m, SNDCTL_DSP_POST);
+ #ifdef SNDCTL_DSP_PROFILE
[email protected]@ -1265,6 +1271,7 @@
+ _EXPORT_INT(m, SNDCTL_DSP_STEREO);
+ _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE);
+ _EXPORT_INT(m, SNDCTL_DSP_SYNC);
++#ifndef __sun
+ _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE);
+ _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR);
+ _EXPORT_INT(m, SNDCTL_MIDI_INFO);
[email protected]@ -1306,5 +1313,6 @@
+ _EXPORT_INT(m, SNDCTL_TMR_STOP);
+ _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
+ _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
++#endif
+ return m;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/15-include.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,14 @@
+On Solaris pyconfig.h is delivered in the normal python header directory.
+As this is Solaris-specific, it is not suitable for upstream.
+
+--- Python-3.5.0a4/Lib/distutils/sysconfig.py.~1~ 2015-04-20 00:37:51.000000000 -0700
++++ Python-3.5.0a4/Lib/distutils/sysconfig.py 2015-04-20 13:50:39.821555060 -0700
[email protected]@ -231,7 +231,7 @@
+ else:
+ inc_dir = _sys_home or project_base
+ else:
+- inc_dir = get_python_inc(plat_specific=1)
++ inc_dir = get_python_inc(plat_specific=0)
+
+ return os.path.join(inc_dir, 'pyconfig.h')
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/16-pic-compile.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,27 @@
+This patch is a Solaris-specific hack; it will not be submitted upstream.
+
+--- Python-3.5.0a4/Lib/distutils/sysconfig.py.~2~ 2015-04-20 13:52:42.184303501 -0700
++++ Python-3.5.0a4/Lib/distutils/sysconfig.py 2015-04-20 13:52:42.193807107 -0700
[email protected]@ -210,6 +210,22 @@
+ else:
+ archiver = ar + ' ' + ar_flags
+
++ # Force PIC compilation. Determine if GNU compiler or otherwise
++ # and set the PIC flag(s) accordingly. Defaults to Studio compiler.
++ if re.search('-.PIC', cflags) == None:
++ try:
++ out = os.popen(cc + ' --version 2>/dev/null', 'r')
++ out_string = out.read()
++ out.close()
++ result = re.search(' (\d+\.\d+(\.\d+)*)', out_string)
++ kpic_flags = "-fPIC -DPIC" if result else "-KPIC -DPIC"
++ except ImportError:
++ # The only time the above should fail is during boot-strapping
++ # when time (os imports subprocess which imports time) is not
++ # yet available. Assume Studio compiler for that case.
++ kpic_flags = "-KPIC -DPIC"
++ cflags += ' ' + kpic_flags
++
+ cc_cmd = cc + ' ' + cflags
+ compiler.set_executables(
+ preprocessor=cpp,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/17-frozen-path.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,14 @@
+This patch has been submitted upstream, but has not yet been accepted.
+http://bugs.python.org/issue22148
+
+--- Python-3.5.0rc2/Python/frozen.c.~1~ 2015-09-02 12:34:23.968577363 -0700
++++ Python-3.5.0rc2/Python/frozen.c 2015-09-02 12:36:35.494526130 -0700
[email protected]@ -2,7 +2,7 @@
+ /* Dummy frozen modules initializer */
+
+ #include "Python.h"
+-#include "importlib.h"
++#include <importlib.h>
+ #include "importlib_external.h"
+
+ /* In order to test the support for frozen modules, by default we
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/19-SOABI.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,14 @@
+This patch was developed in-house. We have not yet decided whether to offer
+it upstream or not.
+
+--- Python-3.5.0a4/configure.ac.~3~ 2015-04-20 14:10:42.056744800 -0700
++++ Python-3.5.0a4/configure.ac 2015-04-20 14:10:42.275328447 -0700
[email protected]@ -4369,7 +4369,7 @@
+
+ AC_SUBST(EXT_SUFFIX)
+ case $ac_sys_system in
+- Linux*|GNU*|Darwin)
++ Linux*|GNU*|Darwin|SunOS)
+ EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
+ *)
+ EXT_SUFFIX=${SHLIB_SUFFIX};;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/20-disable-sslv3.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,59 @@
+This patch comes from in-house. It has not yet been submitted upstream,
+but submission is planned.
+
+--- Python-3.5.0rc2/Modules/_ssl.c.~1~ 2015-08-25 10:19:14.000000000 -0700
++++ Python-3.5.0rc2/Modules/_ssl.c 2015-09-02 12:37:20.276035208 -0700
[email protected]@ -2281,6 +2281,8 @@
+ options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+ if (proto_version != PY_SSL_VERSION_SSL2)
+ options |= SSL_OP_NO_SSLv2;
++ if (proto_version != PY_SSL_VERSION_SSL3)
++ options |= SSL_OP_NO_SSLv3;
+ SSL_CTX_set_options(self->ctx, options);
+
+ #ifndef OPENSSL_NO_ECDH
+--- Python-3.5.0a4/Lib/test/test_ssl.py.~1~ 2015-04-20 00:37:52.000000000 -0700
++++ Python-3.5.0a4/Lib/test/test_ssl.py 2015-04-20 14:13:10.974024879 -0700
[email protected]@ -784,10 +784,7 @@
+ @skip_if_broken_ubuntu_ssl
+ def test_options(self):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+- # OP_ALL | OP_NO_SSLv2 is the default value
+- self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
+- ctx.options)
+- ctx.options |= ssl.OP_NO_SSLv3
++ # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
+ self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
+ ctx.options)
+ if can_clear_options():
[email protected]@ -2451,17 +2448,17 @@
+ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
+ % str(x))
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3')
++ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
+
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
++ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
+
+ if hasattr(ssl, 'PROTOCOL_SSLv3'):
+- try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
++ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
+ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
+
[email protected]@ -2493,7 +2490,8 @@
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
+ if no_sslv2_implies_sslv3_hello():
+ # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
+- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3',
++ # until we disabled SSLv3 for Poodle
++ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
+ client_options=ssl.OP_NO_SSLv2)
+
+ @skip_if_broken_ubuntu_ssl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/21-default-lib-path.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,41 @@
+This patch was developed in-house. It has been submitted upstream:
+http://bugs.python.org/issue23287
+
+--- Python-3.5.0a4/Lib/ctypes/util.py.~1~ 2015-04-20 00:37:51.000000000 -0700
++++ Python-3.5.0a4/Lib/ctypes/util.py 2015-04-20 14:14:06.541902625 -0700
[email protected]@ -175,23 +175,11 @@
+
+ elif sys.platform == "sunos5":
+
+- def _findLib_crle(name, is64):
+- if not os.path.exists('/usr/bin/crle'):
+- return None
+-
++ def _findLib_path(name, is64):
+ if is64:
+- cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null'
++ paths = "/lib/64:/usr/lib/64"
+ else:
+- cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null'
+-
+- with contextlib.closing(os.popen(cmd)) as f:
+- for line in f.readlines():
+- line = line.strip()
+- if line.startswith('Default Library Path (ELF):'):
+- paths = line.split()[4]
+-
+- if not paths:
+- return None
++ paths = "/lib:/usr/lib"
+
+ for dir in paths.split(":"):
+ libfile = os.path.join(dir, "lib%s.so" % name)
[email protected]@ -201,7 +189,7 @@
+ return None
+
+ def find_library(name, is64 = False):
+- return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name))
++ return _get_soname(_findLib_path(name, is64) or _findLib_gcc(name))
+
+ else:
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/22-disable-test_gdb.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,15 @@
+This patch was written in-house, but ported from Python 2.7; it is unclear
+from the version history why these lines were dropped in version 3. The
+patch has not yet been submitted upstream, but submission is planned.
+
+--- Python-3.4.2/Lib/test/test_gdb.py.~1~ 2014-10-08 01:18:13.000000000 -0700
++++ Python-3.4.2/Lib/test/test_gdb.py 2015-02-06 16:00:58.802170301 -0800
[email protected]@ -34,6 +34,8 @@
+ if gdb_major_version < 7:
+ raise unittest.SkipTest("gdb versions before 7.0 didn't support python embedding"
+ " Saw:\n" + gdb_version.decode('ascii', 'replace'))
++if sys.platform.startswith("sunos"):
++ raise unittest.SkipTest("test doesn't work very well on Solaris")
+
+ if not sysconfig.is_python_build():
+ raise unittest.SkipTest("test_gdb only works on source builds at the moment.")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/23-doctest.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,23 @@
+This patch was developed in-house and has been submitted upstream:
+http://bugs.python.org/issue23584
+
+--- Python-3.5.0a4/Lib/test/test_doctest.py.~1~ 2015-04-20 00:37:51.000000000 -0700
++++ Python-3.5.0a4/Lib/test/test_doctest.py 2015-04-20 14:15:20.031951150 -0700
[email protected]@ -2647,7 +2647,7 @@
+ >>> with open(fn, 'wb') as f:
+ ... f.write(b'Test:\r\n\r\n >>> x = 1 + 1\r\n\r\nDone.\r\n')
+ 35
+- >>> doctest.testfile(fn, False)
++ >>> doctest.testfile(fn, False, verbose=False)
+ TestResults(failed=0, attempted=1)
+ >>> os.remove(fn)
+
[email protected]@ -2657,7 +2657,7 @@
+ >>> with open(fn, 'wb') as f:
+ ... f.write(b'Test:\n\n >>> x = 1 + 1\n\nDone.\n')
+ 30
+- >>> doctest.testfile(fn, False)
++ >>> doctest.testfile(fn, False, verbose=False)
+ TestResults(failed=0, attempted=1)
+ >>> os.remove(fn)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/24-gethostname.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,17 @@
+This patch was adapted from a 2.6 patch which came from upstream:
+http://bugs.python.org/issue19561
+
+--- Python-3.5.0a4/Include/pyport.h.~1~ 2015-04-20 00:37:51.000000000 -0700
++++ Python-3.5.0a4/Include/pyport.h 2015-04-20 14:17:45.716965529 -0700
[email protected]@ -640,11 +640,6 @@
+ in platform-specific #ifdefs.
+ **************************************************************************/
+
+-#ifdef SOLARIS
+-/* Unchecked */
+-extern int gethostname(char *, int);
+-#endif
+-
+ #ifdef HAVE__GETPTY
+ #include <sys/types.h> /* we need to import mode_t */
+ extern char * _getpty(int *, int, mode_t, int);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/25-test_site.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,24 @@
+This patch came from in-house. A patch to make -I imply -S was submitted
+upstream, but rejected, so this is the next simplest way to work around
+issues with when the site module is imported.
+
+--- Python-3.5.0rc2/Lib/test/test_site.py.~1~ 2015-08-25 10:19:13.000000000 -0700
++++ Python-3.5.0rc2/Lib/test/test_site.py 2015-09-02 12:38:45.356337855 -0700
[email protected]@ -438,7 +438,7 @@
+ def test_startup_imports(self):
+ # This tests checks which modules are loaded by Python when it
+ # initially starts upon startup.
+- popen = subprocess.Popen([sys.executable, '-I', '-v', '-c',
++ popen = subprocess.Popen([sys.executable, '-I', '-S', '-v', '-c',
+ 'import sys; print(set(sys.modules))'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
[email protected]@ -447,8 +447,6 @@
+ stderr = stderr.decode('utf-8')
+ modules = eval(stdout)
+
+- self.assertIn('site', modules)
+-
+ # http://bugs.python.org/issue19205
+ re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'}
+ # _osx_support uses the re module in many placs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/26-getrandom.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,15 @@
+This patch was originated in-house. It is to work around a bug (21825650)
+in getrandom(2). Once that bug is fixed, the patch should be removable.
+Upstream has been informed.
+
+--- Python-3.5.0rc2/Python/random.c.~1~ 2015-08-25 10:19:14.000000000 -0700
++++ Python-3.5.0rc2/Python/random.c 2015-09-02 14:18:51.799090171 -0700
[email protected]@ -136,7 +136,7 @@
+ }
+
+ if (n < 0) {
+- if (errno == ENOSYS) {
++ if (errno == ENOSYS || errno == EINVAL) {
+ getrandom_works = 0;
+ return 0;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/27-getrandom.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,295 @@
+This patch comes from upstream: http://bugs.python.org/issue25003
+
+--- a/configure Fri Sep 11 12:38:27 2015 +0200
++++ b/configure Fri Sep 11 13:06:42 2015 +0200
[email protected]@ -16180,11 +16180,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_
+ #include <sys/syscall.h>
+
+ int main() {
++ char buffer[1];
++ const size_t buflen = sizeof(buffer);
+ const int flags = 0;
+- char buffer[1];
+- int n;
+ /* ignore the result, Python checks for ENOSYS at runtime */
+- (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
++ (void)syscall(SYS_getrandom, buffer, buflen, flags);
+ return 0;
+ }
+
[email protected]@ -16206,6 +16206,43 @@ if test "$have_getrandom_syscall" = yes;
+
+ fi
+
++# check if the getrandom() function is available
++# the test was written for the Solaris function of <sys/random.h>
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5
++$as_echo_n "checking for the getrandom() function... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++
++ #include <sys/random.h>
++
++ int main() {
++ char buffer[1];
++ const size_t buflen = sizeof(buffer);
++ const int flags = 0;
++ /* ignore the result, Python checks for ENOSYS at runtime */
++ (void)getrandom(buffer, buflen, flags);
++ return 0;
++ }
++
++
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ have_getrandom=yes
++else
++ have_getrandom=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getrandom" >&5
++$as_echo "$have_getrandom" >&6; }
++
++if test "$have_getrandom" = yes; then
++
++$as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h
++
++fi
++
+ # generate output files
+ ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
+
+--- a/configure.ac Fri Sep 11 12:38:27 2015 +0200
++++ b/configure.ac Fri Sep 11 13:06:42 2015 +0200
[email protected]@ -5161,11 +5161,11 @@ AC_LINK_IFELSE(
+ #include <sys/syscall.h>
+
+ int main() {
++ char buffer[1];
++ const size_t buflen = sizeof(buffer);
+ const int flags = 0;
+- char buffer[1];
+- int n;
+ /* ignore the result, Python checks for ENOSYS at runtime */
+- (void)syscall(SYS_getrandom, buffer, sizeof(buffer), flags);
++ (void)syscall(SYS_getrandom, buffer, buflen, flags);
+ return 0;
+ }
+ ]])
[email protected]@ -5177,6 +5177,31 @@ if test "$have_getrandom_syscall" = yes;
+ [Define to 1 if the Linux getrandom() syscall is available])
+ fi
+
++# check if the getrandom() function is available
++# the test was written for the Solaris function of <sys/random.h>
++AC_MSG_CHECKING(for the getrandom() function)
++AC_LINK_IFELSE(
++[
++ AC_LANG_SOURCE([[
++ #include <sys/random.h>
++
++ int main() {
++ char buffer[1];
++ const size_t buflen = sizeof(buffer);
++ const int flags = 0;
++ /* ignore the result, Python checks for ENOSYS at runtime */
++ (void)getrandom(buffer, buflen, flags);
++ return 0;
++ }
++ ]])
++],[have_getrandom=yes],[have_getrandom=no])
++AC_MSG_RESULT($have_getrandom)
++
++if test "$have_getrandom" = yes; then
++ AC_DEFINE(HAVE_GETRANDOM, 1,
++ [Define to 1 if the getrandom() function is available])
++fi
++
+ # generate output files
+ AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
+ AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
+--- Python-3.5.0/Lib/test/test_os.py.~1~ 2015-09-13 04:41:23.000000000 -0700
++++ Python-3.5.0/Lib/test/test_os.py 2015-09-14 13:43:47.884863398 -0700
[email protected]@ -1213,13 +1213,17 @@
+ self.assertNotEqual(data1, data2)
+
+
+-HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
+-HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
++USE_GETENTROPY = ((sysconfig.get_config_var('HAVE_GETENTROPY') == 1)
++ and not sys.platform.startswith("sunos"))
++HAVE_GETRANDOM = (sysconfig.get_config_var('HAVE_GETRANDOM') == 1)
++HAVE_GETRANDOM_SYSCALL = (sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
+
[email protected](HAVE_GETENTROPY,
[email protected](USE_GETENTROPY,
+ "getentropy() does not use a file descriptor")
+ @unittest.skipIf(HAVE_GETRANDOM,
+ "getrandom() does not use a file descriptor")
[email protected](HAVE_GETRANDOM_SYSCALL,
++ "getrandom() does not use a file descriptor")
+ class URandomFDTests(unittest.TestCase):
+ @unittest.skipUnless(resource, "test requires the resource module")
+ def test_urandom_failure(self):
+--- Python-3.5.0/Python/random.c.~2~ 2015-09-14 14:11:43.377801246 -0700
++++ Python-3.5.0/Python/random.c 2015-09-14 14:19:35.124606276 -0700
[email protected]@ -6,11 +6,20 @@
+ # ifdef HAVE_SYS_STAT_H
+ # include <sys/stat.h>
+ # endif
+-# ifdef HAVE_GETRANDOM_SYSCALL
++# ifdef HAVE_GETRANDOM
++# include <sys/random.h>
++# elif defined(HAVE_GETRANDOM_SYSCALL)
+ # include <sys/syscall.h>
+ # endif
+ #endif
+
++/* Solaris 11.3 provides getrandom() and getentropy(). getentropy() cannot be
++ used for os.urandom() because it is blocking, it. Use
++ getrandom(GRND_NONBLOCK) instead, it is non-blocking. */
++#if defined(HAVE_GETENTROPY) && !defined(sun)
++# define USE_GETENTROPY
++#endif
++
+ #ifdef Py_DEBUG
+ int _Py_HashSecret_Initialized = 0;
+ #else
[email protected]@ -70,7 +79,7 @@
+ return 0;
+ }
+
+-#elif HAVE_GETENTROPY
++#elif defined(USE_GETENTROPY)
+ /* Fill buffer with size pseudo-random bytes generated by getentropy().
+ Return 0 on success, or raise an exception and return -1 on error.
+
[email protected]@ -105,16 +114,19 @@
+ return 0;
+ }
+
+-#else /* !HAVE_GETENTROPY */
++#else /* !USE_GETENTROPY */
++
++#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
++#define PY_GETRANDOM
+
+-#ifdef HAVE_GETRANDOM_SYSCALL
+ static int
+ py_getrandom(void *buffer, Py_ssize_t size, int raise)
+ {
+- /* is getrandom() supported by the running kernel?
+- * need Linux kernel 3.17 or later */
++ /* Is getrandom() supported by the running kernel?
++ * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */
+ static int getrandom_works = 1;
+- /* Use /dev/urandom, block if the kernel has no entropy */
++ /* Use non-blocking /dev/urandom device. On Linux at boot, the getrandom()
++ * syscall blocks until /dev/urandom is initialized with enough entropy. */
+ const int flags = 0;
+ int n;
+
[email protected]@ -124,7 +136,18 @@
+ while (0 < size) {
+ errno = 0;
+
+- /* Use syscall() because the libc doesn't expose getrandom() yet, see:
++#ifdef HAVE_GETRANDOM
++ if (raise) {
++ Py_BEGIN_ALLOW_THREADS
++ n = getrandom(buffer, size, flags);
++ Py_END_ALLOW_THREADS
++ }
++ else {
++ n = getrandom(buffer, size, flags);
++ }
++#else
++ /* On Linux, use the syscall() function because the GNU libc doesn't
++ * expose the Linux getrandom() syscall yet. See:
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
+ if (raise) {
+ Py_BEGIN_ALLOW_THREADS
[email protected]@ -134,6 +157,7 @@
+ else {
+ n = syscall(SYS_getrandom, buffer, size, flags);
+ }
++#endif
+
+ if (n < 0) {
+ if (errno == ENOSYS || errno == EINVAL) {
[email protected]@ -182,7 +206,7 @@
+
+ assert (0 < size);
+
+-#ifdef HAVE_GETRANDOM_SYSCALL
++#ifdef PY_GETRANDOM
+ if (py_getrandom(buffer, size, 0) == 1)
+ return;
+ /* getrandom() is not supported by the running kernel, fall back
[email protected]@ -218,14 +242,14 @@
+ int fd;
+ Py_ssize_t n;
+ struct _Py_stat_struct st;
+-#ifdef HAVE_GETRANDOM_SYSCALL
++#ifdef PY_GETRANDOM
+ int res;
+ #endif
+
+ if (size <= 0)
+ return 0;
+
+-#ifdef HAVE_GETRANDOM_SYSCALL
++#ifdef PY_GETRANDOM
+ res = py_getrandom(buffer, size, 1);
+ if (res < 0)
+ return -1;
[email protected]@ -304,7 +328,7 @@
+ }
+ }
+
+-#endif /* HAVE_GETENTROPY */
++#endif
+
+ /* Fill buffer with pseudo-random bytes generated by a linear congruent
+ generator (LCG):
[email protected]@ -345,7 +369,7 @@
+
+ #ifdef MS_WINDOWS
+ return win32_urandom((unsigned char *)buffer, size, 1);
+-#elif HAVE_GETENTROPY
++#elif defined(USE_GETENTROPY)
+ return py_getentropy(buffer, size, 0);
+ #else
+ return dev_urandom_python((char*)buffer, size);
[email protected]@ -392,7 +416,7 @@
+ else {
+ #ifdef MS_WINDOWS
+ (void)win32_urandom(secret, secret_size, 0);
+-#elif HAVE_GETENTROPY
++#elif defined(USE_GETENTROPY)
+ (void)py_getentropy(secret, secret_size, 1);
+ #else
+ dev_urandom_noraise(secret, secret_size);
[email protected]@ -408,7 +432,7 @@
+ CryptReleaseContext(hCryptProv, 0);
+ hCryptProv = 0;
+ }
+-#elif HAVE_GETENTROPY
++#elif defined(USE_GETENTROPY)
+ /* nothing to clean */
+ #else
+ dev_urandom_close();
+--- a/pyconfig.h.in Fri Sep 11 12:38:27 2015 +0200
++++ b/pyconfig.h.in Fri Sep 11 13:06:42 2015 +0200
[email protected]@ -395,6 +395,9 @@
+ /* Define to 1 if you have the `getpwent' function. */
+ #undef HAVE_GETPWENT
+
++/* Define to 1 if the getrandom() function is available */
++#undef HAVE_GETRANDOM
++
+ /* Define to 1 if the Linux getrandom() syscall is available */
+ #undef HAVE_GETRANDOM_SYSCALL
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/patches/28-test-vmlimit.patch Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,26 @@
+This patch for a Solaris-specific problem but is a good safety precaution,
+so although it is not suitable for upstream as-is, we might offer it in a
+slightly tweaked form at some point in the future.
+
+--- Python-3.5.0/Lib/test/regrtest.py.~1~ 2015-09-13 04:41:22.000000000 -0700
++++ Python-3.5.0/Lib/test/regrtest.py 2015-09-14 14:42:45.764365598 -0700
[email protected]@ -187,6 +187,19 @@
+ newsoft = min(hard, max(soft, 1024*2048))
+ resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard))
+
++# The socket test goes crazy on Solaris, slurping up VM until the system
++# dies or the test is killed. So limit it to 4GB. While we could do this
++# in the socket test itself, it is more prudent to do it here in case any
++# other tests ever go crazy in a similar fashion.
++if sys.platform == 'sunos5':
++ try:
++ import resource
++ except ImportError:
++ pass
++ else:
++ vm_limit = 4294967296
++ resource.setrlimit(resource.RLIMIT_VMEM, (vm_limit, vm_limit))
++
+ # Test result constants.
+ PASSED = 1
+ FAILED = 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/python35/python-35.p5m Tue Sep 29 14:11:08 2015 -0700
@@ -0,0 +1,2151 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+#
+# Bootstrap: pkgdepend doesn't like python 3.5 yet;
+# remove this block once it is installed on build machines.
+# Also look for other "XXX bootstrap" comments.
+<transform file path=.+\.py$ -> \
+ default pkg.depend.bypass-generate .* >
+<transform file path=.+\.pyc$ -> \
+ default pkg.depend.bypass-generate .* >
+<transform file path=usr/bin.*$ -> \
+ default pkg.depend.bypass-generate .* >
+#
+<transform file path=usr/lib/python3.5/lib-dynload/.*\.so -> \
+ add pkg.linted.userland.action001.2 true>
+<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
+<transform file path=.*/(idle_)?tests?/.* -> default facet.optional.test true>
+set name=pkg.fmri \
+ value=pkg:/runtime/[email protected]$(COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary value="The Python interpreter, libraries and utilities"
+set name=com.oracle.info.description value="Python 3.5"
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification \
+ value=org.opensolaris.category.2008:Development/Python
+set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
+set name=org.opensolaris.arc-caseid value=PSARC/2005/555 value=PSARC/2008/514 \
+ value=PSARC/2009/529 value=PSARC/2013/235 value=PSARC/2014/151 \
+ value=PSARC/2015/414
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+#
+link path=usr/bin/2to3 target=2to3-3.5 mediator=python mediator-version=3.5
+file path=usr/bin/2to3-3.5
+link path=usr/bin/idle target=idle3.5 mediator=python mediator-version=3.5
+file path=usr/bin/idle3.5
+link path=usr/bin/pydoc target=pydoc3.5 mediator=python mediator-version=3.5
+file path=usr/bin/pydoc3.5
+link path=usr/bin/python target=python3.5 mediator=python mediator-version=3.5
+link path=usr/bin/python-config target=python3.5-config mediator=python \
+ mediator-version=3.5
+hardlink path=usr/bin/python3.5 target=python3.5m
+link path=usr/bin/python3.5-config target=python3.5m-config
+file path=usr/bin/python3.5m
+file path=usr/bin/python3.5m-config
+link path=usr/bin/pyvenv target=pyvenv-3.5 mediator=python mediator-version=3.5
+file path=usr/bin/pyvenv-3.5
+#
+file path=usr/include/python3.5m/Python-ast.h
+file path=usr/include/python3.5m/Python.h
+file path=usr/include/python3.5m/abstract.h
+file path=usr/include/python3.5m/accu.h
+file path=usr/include/python3.5m/asdl.h
+file path=usr/include/python3.5m/ast.h
+file path=usr/include/python3.5m/bitset.h
+file path=usr/include/python3.5m/bltinmodule.h
+file path=usr/include/python3.5m/boolobject.h
+file path=usr/include/python3.5m/bytearrayobject.h
+file path=usr/include/python3.5m/bytes_methods.h
+file path=usr/include/python3.5m/bytesobject.h
+file path=usr/include/python3.5m/cellobject.h
+file path=usr/include/python3.5m/ceval.h
+file path=usr/include/python3.5m/classobject.h
+file path=usr/include/python3.5m/code.h
+file path=usr/include/python3.5m/codecs.h
+file path=usr/include/python3.5m/compile.h
+file path=usr/include/python3.5m/complexobject.h
+file path=usr/include/python3.5m/datetime.h
+file path=usr/include/python3.5m/descrobject.h
+file path=usr/include/python3.5m/dictobject.h
+file path=usr/include/python3.5m/dtoa.h
+file path=usr/include/python3.5m/dynamic_annotations.h
+file path=usr/include/python3.5m/enumobject.h
+file path=usr/include/python3.5m/errcode.h
+file path=usr/include/python3.5m/eval.h
+file path=usr/include/python3.5m/fileobject.h
+file path=usr/include/python3.5m/fileutils.h
+file path=usr/include/python3.5m/floatobject.h
+file path=usr/include/python3.5m/frameobject.h
+file path=usr/include/python3.5m/funcobject.h
+file path=usr/include/python3.5m/genobject.h
+file path=usr/include/python3.5m/graminit.h
+file path=usr/include/python3.5m/grammar.h
+file path=usr/include/python3.5m/import.h
+file path=usr/include/python3.5m/intrcheck.h
+file path=usr/include/python3.5m/iterobject.h
+file path=usr/include/python3.5m/listobject.h
+file path=usr/include/python3.5m/longintrepr.h
+file path=usr/include/python3.5m/longobject.h
+file path=usr/include/python3.5m/marshal.h
+file path=usr/include/python3.5m/memoryobject.h
+file path=usr/include/python3.5m/metagrammar.h
+file path=usr/include/python3.5m/methodobject.h
+file path=usr/include/python3.5m/modsupport.h
+file path=usr/include/python3.5m/moduleobject.h
+file path=usr/include/python3.5m/namespaceobject.h
+file path=usr/include/python3.5m/node.h
+file path=usr/include/python3.5m/object.h
+file path=usr/include/python3.5m/objimpl.h
+file path=usr/include/python3.5m/odictobject.h
+file path=usr/include/python3.5m/opcode.h
+file path=usr/include/python3.5m/osdefs.h
+file path=usr/include/python3.5m/parsetok.h
+file path=usr/include/python3.5m/patchlevel.h
+file path=usr/include/python3.5m/pgen.h
+file path=usr/include/python3.5m/pgenheaders.h
+file path=usr/include/python3.5m/py_curses.h
+file path=usr/include/python3.5m/pyarena.h
+file path=usr/include/python3.5m/pyatomic.h
+file path=usr/include/python3.5m/pycapsule.h
+file path=usr/include/python3.5m/pyconfig.h
+file path=usr/include/python3.5m/pyctype.h
+file path=usr/include/python3.5m/pydebug.h
+file path=usr/include/python3.5m/pydtrace.h
+file path=usr/include/python3.5m/pydtrace_offsets.h
+file path=usr/include/python3.5m/pyerrors.h
+file path=usr/include/python3.5m/pyexpat.h
+file path=usr/include/python3.5m/pyfpe.h
+file path=usr/include/python3.5m/pygetopt.h
+file path=usr/include/python3.5m/pyhash.h
+file path=usr/include/python3.5m/pylifecycle.h
+file path=usr/include/python3.5m/pymacconfig.h
+file path=usr/include/python3.5m/pymacro.h
+file path=usr/include/python3.5m/pymath.h
+file path=usr/include/python3.5m/pymem.h
+file path=usr/include/python3.5m/pyport.h
+file path=usr/include/python3.5m/pystate.h
+file path=usr/include/python3.5m/pystrcmp.h
+file path=usr/include/python3.5m/pystrhex.h
+file path=usr/include/python3.5m/pystrtod.h
+file path=usr/include/python3.5m/pythonrun.h
+file path=usr/include/python3.5m/pythread.h
+file path=usr/include/python3.5m/pytime.h
+file path=usr/include/python3.5m/rangeobject.h
+file path=usr/include/python3.5m/setobject.h
+file path=usr/include/python3.5m/sliceobject.h
+file path=usr/include/python3.5m/structmember.h
+file path=usr/include/python3.5m/structseq.h
+file path=usr/include/python3.5m/symtable.h
+file path=usr/include/python3.5m/sysmodule.h
+file path=usr/include/python3.5m/token.h
+file path=usr/include/python3.5m/traceback.h
+file path=usr/include/python3.5m/tupleobject.h
+file path=usr/include/python3.5m/typeslots.h
+file path=usr/include/python3.5m/ucnhash.h
+file path=usr/include/python3.5m/unicodeobject.h
+file path=usr/include/python3.5m/warnings.h
+file path=usr/include/python3.5m/weakrefobject.h
+link path=usr/lib/$(MACH64)/libpython3.5m.so target=libpython3.5m.so.1.0
+file path=usr/lib/$(MACH64)/libpython3.5m.so.1.0
+link path=usr/lib/$(MACH64)/libpython3.5m_db.so target=libpython3.5m_db.so.1.0
+file path=usr/lib/$(MACH64)/libpython3.5m_db.so.1.0
+file path=usr/lib/$(MACH64)/pkgconfig/python-3.5.pc
+link path=usr/lib/$(MACH64)/pkgconfig/python3.pc target=python-3.5.pc \
+ mediator=python mediator-version=3.5
+link path=usr/lib/pkgconfig/python-3.5.pc \
+ target=../$(MACH64)/pkgconfig/python-3.5.pc
+link path=usr/lib/pkgconfig/python3.pc target=python-3.5.pc mediator=python \
+ mediator-version=3.5
+file path=usr/lib/python3.5/LICENSE.txt
+file path=usr/lib/python3.5/__future__.py
+file path=usr/lib/python3.5/__phello__.foo.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/_bootlocale.py
+file path=usr/lib/python3.5/_collections_abc.py
+file path=usr/lib/python3.5/_compat_pickle.py
+file path=usr/lib/python3.5/_compression.py
+file path=usr/lib/python3.5/_dummy_thread.py
+file path=usr/lib/python3.5/_markupbase.py
+file path=usr/lib/python3.5/_osx_support.py
+file path=usr/lib/python3.5/_pydecimal.py
+file path=usr/lib/python3.5/_pyio.py
+file path=usr/lib/python3.5/_sitebuiltins.py
+file path=usr/lib/python3.5/_strptime.py
+file path=usr/lib/python3.5/_sysconfigdata.py
+file path=usr/lib/python3.5/_threading_local.py
+file path=usr/lib/python3.5/_weakrefset.py
+file path=usr/lib/python3.5/abc.py
+file path=usr/lib/python3.5/aifc.py
+file path=usr/lib/python3.5/antigravity.py
+file path=usr/lib/python3.5/argparse.py
+file path=usr/lib/python3.5/ast.py
+file path=usr/lib/python3.5/asynchat.py
+file path=usr/lib/python3.5/asyncio/__init__.py
+file path=usr/lib/python3.5/asyncio/base_events.py
+file path=usr/lib/python3.5/asyncio/base_subprocess.py
+file path=usr/lib/python3.5/asyncio/compat.py
+file path=usr/lib/python3.5/asyncio/constants.py
+file path=usr/lib/python3.5/asyncio/coroutines.py
+file path=usr/lib/python3.5/asyncio/events.py
+file path=usr/lib/python3.5/asyncio/futures.py
+file path=usr/lib/python3.5/asyncio/locks.py
+file path=usr/lib/python3.5/asyncio/log.py
+file path=usr/lib/python3.5/asyncio/proactor_events.py
+file path=usr/lib/python3.5/asyncio/protocols.py
+file path=usr/lib/python3.5/asyncio/queues.py
+file path=usr/lib/python3.5/asyncio/selector_events.py
+file path=usr/lib/python3.5/asyncio/sslproto.py
+file path=usr/lib/python3.5/asyncio/streams.py
+file path=usr/lib/python3.5/asyncio/subprocess.py
+file path=usr/lib/python3.5/asyncio/tasks.py
+file path=usr/lib/python3.5/asyncio/test_utils.py
+file path=usr/lib/python3.5/asyncio/transports.py
+file path=usr/lib/python3.5/asyncio/unix_events.py
+file path=usr/lib/python3.5/asyncio/windows_events.py
+file path=usr/lib/python3.5/asyncio/windows_utils.py
+file path=usr/lib/python3.5/asyncore.py
+file path=usr/lib/python3.5/base64.py
+file path=usr/lib/python3.5/bdb.py
+file path=usr/lib/python3.5/binhex.py
+file path=usr/lib/python3.5/bisect.py
+file path=usr/lib/python3.5/bz2.py
+file path=usr/lib/python3.5/cProfile.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/calendar.py
+file path=usr/lib/python3.5/cgi.py
+file path=usr/lib/python3.5/cgitb.py
+file path=usr/lib/python3.5/chunk.py
+file path=usr/lib/python3.5/cmd.py
+file path=usr/lib/python3.5/code.py
+file path=usr/lib/python3.5/codecs.py
+file path=usr/lib/python3.5/codeop.py
+file path=usr/lib/python3.5/collections/__init__.py
+file path=usr/lib/python3.5/collections/__main__.py
+file path=usr/lib/python3.5/collections/abc.py
+file path=usr/lib/python3.5/colorsys.py
+file path=usr/lib/python3.5/compileall.py
+file path=usr/lib/python3.5/concurrent/__init__.py
+file path=usr/lib/python3.5/concurrent/futures/__init__.py
+file path=usr/lib/python3.5/concurrent/futures/_base.py
+file path=usr/lib/python3.5/concurrent/futures/process.py
+file path=usr/lib/python3.5/concurrent/futures/thread.py
+file path=usr/lib/python3.5/config-3.5m/Makefile
+file path=usr/lib/python3.5/config-3.5m/Setup
+file path=usr/lib/python3.5/config-3.5m/Setup.config
+file path=usr/lib/python3.5/config-3.5m/Setup.local
+file path=usr/lib/python3.5/config-3.5m/config.c
+file path=usr/lib/python3.5/config-3.5m/config.c.in
+file path=usr/lib/python3.5/config-3.5m/install-sh
+file path=usr/lib/python3.5/config-3.5m/libpython3.5m.a
+file path=usr/lib/python3.5/config-3.5m/makesetup
+file path=usr/lib/python3.5/config-3.5m/python-config.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/config-3.5m/python.o \
+ pkg.linted.userland.action001.2=true
+file path=usr/lib/python3.5/configparser.py
+file path=usr/lib/python3.5/contextlib.py
+file path=usr/lib/python3.5/copy.py
+file path=usr/lib/python3.5/copyreg.py
+file path=usr/lib/python3.5/crypt.py
+file path=usr/lib/python3.5/csv.py
+file path=usr/lib/python3.5/ctypes/__init__.py
+file path=usr/lib/python3.5/ctypes/_endian.py
+file path=usr/lib/python3.5/ctypes/macholib/README.ctypes
+file path=usr/lib/python3.5/ctypes/macholib/__init__.py
+file path=usr/lib/python3.5/ctypes/macholib/dyld.py
+file path=usr/lib/python3.5/ctypes/macholib/dylib.py
+file path=usr/lib/python3.5/ctypes/macholib/fetch_macholib
+file path=usr/lib/python3.5/ctypes/macholib/fetch_macholib.bat
+file path=usr/lib/python3.5/ctypes/macholib/framework.py
+#
+file path=usr/lib/python3.5/ctypes/test/__init__.py
+file path=usr/lib/python3.5/ctypes/test/__main__.py
+file path=usr/lib/python3.5/ctypes/test/test_anon.py
+file path=usr/lib/python3.5/ctypes/test/test_array_in_pointer.py
+file path=usr/lib/python3.5/ctypes/test/test_arrays.py
+file path=usr/lib/python3.5/ctypes/test/test_as_parameter.py
+file path=usr/lib/python3.5/ctypes/test/test_bitfields.py
+file path=usr/lib/python3.5/ctypes/test/test_buffers.py
+file path=usr/lib/python3.5/ctypes/test/test_bytes.py
+file path=usr/lib/python3.5/ctypes/test/test_byteswap.py
+file path=usr/lib/python3.5/ctypes/test/test_callbacks.py
+file path=usr/lib/python3.5/ctypes/test/test_cast.py
+file path=usr/lib/python3.5/ctypes/test/test_cfuncs.py
+file path=usr/lib/python3.5/ctypes/test/test_checkretval.py
+file path=usr/lib/python3.5/ctypes/test/test_delattr.py
+file path=usr/lib/python3.5/ctypes/test/test_errno.py
+file path=usr/lib/python3.5/ctypes/test/test_find.py
+file path=usr/lib/python3.5/ctypes/test/test_frombuffer.py
+file path=usr/lib/python3.5/ctypes/test/test_funcptr.py
+file path=usr/lib/python3.5/ctypes/test/test_functions.py
+file path=usr/lib/python3.5/ctypes/test/test_incomplete.py
+file path=usr/lib/python3.5/ctypes/test/test_init.py
+file path=usr/lib/python3.5/ctypes/test/test_internals.py
+file path=usr/lib/python3.5/ctypes/test/test_keeprefs.py
+file path=usr/lib/python3.5/ctypes/test/test_libc.py
+file path=usr/lib/python3.5/ctypes/test/test_loading.py
+file path=usr/lib/python3.5/ctypes/test/test_macholib.py
+file path=usr/lib/python3.5/ctypes/test/test_memfunctions.py
+file path=usr/lib/python3.5/ctypes/test/test_numbers.py
+file path=usr/lib/python3.5/ctypes/test/test_objects.py
+file path=usr/lib/python3.5/ctypes/test/test_parameters.py
+file path=usr/lib/python3.5/ctypes/test/test_pep3118.py
+file path=usr/lib/python3.5/ctypes/test/test_pickling.py
+file path=usr/lib/python3.5/ctypes/test/test_pointers.py
+file path=usr/lib/python3.5/ctypes/test/test_prototypes.py
+file path=usr/lib/python3.5/ctypes/test/test_python_api.py
+file path=usr/lib/python3.5/ctypes/test/test_random_things.py
+file path=usr/lib/python3.5/ctypes/test/test_refcounts.py
+file path=usr/lib/python3.5/ctypes/test/test_repr.py
+file path=usr/lib/python3.5/ctypes/test/test_returnfuncptrs.py
+file path=usr/lib/python3.5/ctypes/test/test_simplesubclasses.py
+file path=usr/lib/python3.5/ctypes/test/test_sizes.py
+file path=usr/lib/python3.5/ctypes/test/test_slicing.py
+file path=usr/lib/python3.5/ctypes/test/test_stringptr.py
+file path=usr/lib/python3.5/ctypes/test/test_strings.py
+file path=usr/lib/python3.5/ctypes/test/test_struct_fields.py
+file path=usr/lib/python3.5/ctypes/test/test_structures.py
+file path=usr/lib/python3.5/ctypes/test/test_unaligned_structures.py
+file path=usr/lib/python3.5/ctypes/test/test_unicode.py
+file path=usr/lib/python3.5/ctypes/test/test_values.py
+file path=usr/lib/python3.5/ctypes/test/test_varsize_struct.py
+file path=usr/lib/python3.5/ctypes/test/test_win32.py
+file path=usr/lib/python3.5/ctypes/test/test_wintypes.py
+file path=usr/lib/python3.5/ctypes/util.py
+file path=usr/lib/python3.5/ctypes/wintypes.py
+file path=usr/lib/python3.5/curses/__init__.py
+file path=usr/lib/python3.5/curses/ascii.py
+file path=usr/lib/python3.5/curses/has_key.py
+file path=usr/lib/python3.5/curses/panel.py
+file path=usr/lib/python3.5/curses/textpad.py
+file path=usr/lib/python3.5/datetime.py
+file path=usr/lib/python3.5/dbm/__init__.py
+file path=usr/lib/python3.5/dbm/dumb.py
+file path=usr/lib/python3.5/dbm/gnu.py
+file path=usr/lib/python3.5/dbm/ndbm.py
+file path=usr/lib/python3.5/decimal.py
+file path=usr/lib/python3.5/difflib.py
+file path=usr/lib/python3.5/dis.py
+file path=usr/lib/python3.5/distutils/README
+file path=usr/lib/python3.5/distutils/__init__.py
+file path=usr/lib/python3.5/distutils/_msvccompiler.py
+file path=usr/lib/python3.5/distutils/archive_util.py
+file path=usr/lib/python3.5/distutils/bcppcompiler.py
+file path=usr/lib/python3.5/distutils/ccompiler.py
+file path=usr/lib/python3.5/distutils/cmd.py
+file path=usr/lib/python3.5/distutils/command/__init__.py
+file path=usr/lib/python3.5/distutils/command/bdist.py
+file path=usr/lib/python3.5/distutils/command/bdist_dumb.py
+file path=usr/lib/python3.5/distutils/command/bdist_msi.py
+file path=usr/lib/python3.5/distutils/command/bdist_rpm.py
+file path=usr/lib/python3.5/distutils/command/bdist_wininst.py
+file path=usr/lib/python3.5/distutils/command/build.py
+file path=usr/lib/python3.5/distutils/command/build_clib.py
+file path=usr/lib/python3.5/distutils/command/build_ext.py
+file path=usr/lib/python3.5/distutils/command/build_py.py
+file path=usr/lib/python3.5/distutils/command/build_scripts.py
+file path=usr/lib/python3.5/distutils/command/check.py
+file path=usr/lib/python3.5/distutils/command/clean.py
+file path=usr/lib/python3.5/distutils/command/command_template
+file path=usr/lib/python3.5/distutils/command/config.py
+file path=usr/lib/python3.5/distutils/command/install.py
+file path=usr/lib/python3.5/distutils/command/install_data.py
+file path=usr/lib/python3.5/distutils/command/install_egg_info.py
+file path=usr/lib/python3.5/distutils/command/install_headers.py
+file path=usr/lib/python3.5/distutils/command/install_lib.py
+file path=usr/lib/python3.5/distutils/command/install_scripts.py
+file path=usr/lib/python3.5/distutils/command/register.py
+file path=usr/lib/python3.5/distutils/command/sdist.py
+file path=usr/lib/python3.5/distutils/command/upload.py
+file path=usr/lib/python3.5/distutils/command/wininst-10.0-amd64.exe
+file path=usr/lib/python3.5/distutils/command/wininst-10.0.exe
+file path=usr/lib/python3.5/distutils/command/wininst-6.0.exe
+file path=usr/lib/python3.5/distutils/command/wininst-7.1.exe
+file path=usr/lib/python3.5/distutils/command/wininst-8.0.exe
+file path=usr/lib/python3.5/distutils/command/wininst-9.0-amd64.exe
+file path=usr/lib/python3.5/distutils/command/wininst-9.0.exe
+file path=usr/lib/python3.5/distutils/config.py
+file path=usr/lib/python3.5/distutils/core.py
+file path=usr/lib/python3.5/distutils/cygwinccompiler.py
+file path=usr/lib/python3.5/distutils/debug.py
+file path=usr/lib/python3.5/distutils/dep_util.py
+file path=usr/lib/python3.5/distutils/dir_util.py
+file path=usr/lib/python3.5/distutils/dist.py
+file path=usr/lib/python3.5/distutils/errors.py
+file path=usr/lib/python3.5/distutils/extension.py
+file path=usr/lib/python3.5/distutils/fancy_getopt.py
+file path=usr/lib/python3.5/distutils/file_util.py
+file path=usr/lib/python3.5/distutils/filelist.py
+file path=usr/lib/python3.5/distutils/log.py
+file path=usr/lib/python3.5/distutils/msvc9compiler.py
+file path=usr/lib/python3.5/distutils/msvccompiler.py
+file path=usr/lib/python3.5/distutils/spawn.py
+file path=usr/lib/python3.5/distutils/sysconfig.py
+file path=usr/lib/python3.5/distutils/tests/Setup.sample
+file path=usr/lib/python3.5/distutils/tests/__init__.py
+file path=usr/lib/python3.5/distutils/tests/support.py
+file path=usr/lib/python3.5/distutils/tests/test_archive_util.py
+file path=usr/lib/python3.5/distutils/tests/test_bdist.py
+file path=usr/lib/python3.5/distutils/tests/test_bdist_dumb.py
+file path=usr/lib/python3.5/distutils/tests/test_bdist_msi.py
+file path=usr/lib/python3.5/distutils/tests/test_bdist_rpm.py
+file path=usr/lib/python3.5/distutils/tests/test_bdist_wininst.py
+file path=usr/lib/python3.5/distutils/tests/test_build.py
+file path=usr/lib/python3.5/distutils/tests/test_build_clib.py
+file path=usr/lib/python3.5/distutils/tests/test_build_ext.py
+file path=usr/lib/python3.5/distutils/tests/test_build_py.py
+file path=usr/lib/python3.5/distutils/tests/test_build_scripts.py
+file path=usr/lib/python3.5/distutils/tests/test_check.py
+file path=usr/lib/python3.5/distutils/tests/test_clean.py
+file path=usr/lib/python3.5/distutils/tests/test_cmd.py
+file path=usr/lib/python3.5/distutils/tests/test_config.py
+file path=usr/lib/python3.5/distutils/tests/test_config_cmd.py
+file path=usr/lib/python3.5/distutils/tests/test_core.py
+file path=usr/lib/python3.5/distutils/tests/test_cygwinccompiler.py
+file path=usr/lib/python3.5/distutils/tests/test_dep_util.py
+file path=usr/lib/python3.5/distutils/tests/test_dir_util.py
+file path=usr/lib/python3.5/distutils/tests/test_dist.py
+file path=usr/lib/python3.5/distutils/tests/test_extension.py
+file path=usr/lib/python3.5/distutils/tests/test_file_util.py
+file path=usr/lib/python3.5/distutils/tests/test_filelist.py
+file path=usr/lib/python3.5/distutils/tests/test_install.py
+file path=usr/lib/python3.5/distutils/tests/test_install_data.py
+file path=usr/lib/python3.5/distutils/tests/test_install_headers.py
+file path=usr/lib/python3.5/distutils/tests/test_install_lib.py
+file path=usr/lib/python3.5/distutils/tests/test_install_scripts.py
+file path=usr/lib/python3.5/distutils/tests/test_log.py
+file path=usr/lib/python3.5/distutils/tests/test_msvc9compiler.py
+file path=usr/lib/python3.5/distutils/tests/test_msvccompiler.py
+file path=usr/lib/python3.5/distutils/tests/test_register.py
+file path=usr/lib/python3.5/distutils/tests/test_sdist.py
+file path=usr/lib/python3.5/distutils/tests/test_spawn.py
+file path=usr/lib/python3.5/distutils/tests/test_sysconfig.py
+file path=usr/lib/python3.5/distutils/tests/test_text_file.py
+file path=usr/lib/python3.5/distutils/tests/test_unixccompiler.py
+file path=usr/lib/python3.5/distutils/tests/test_upload.py
+file path=usr/lib/python3.5/distutils/tests/test_util.py
+file path=usr/lib/python3.5/distutils/tests/test_version.py
+file path=usr/lib/python3.5/distutils/tests/test_versionpredicate.py
+file path=usr/lib/python3.5/distutils/tests/xxmodule.c
+file path=usr/lib/python3.5/distutils/text_file.py
+file path=usr/lib/python3.5/distutils/unixccompiler.py
+file path=usr/lib/python3.5/distutils/util.py
+file path=usr/lib/python3.5/distutils/version.py
+file path=usr/lib/python3.5/distutils/versionpredicate.py
+file path=usr/lib/python3.5/doctest.py
+file path=usr/lib/python3.5/dummy_threading.py
+file path=usr/lib/python3.5/email/__init__.py
+file path=usr/lib/python3.5/email/_encoded_words.py
+file path=usr/lib/python3.5/email/_header_value_parser.py
+file path=usr/lib/python3.5/email/_parseaddr.py
+file path=usr/lib/python3.5/email/_policybase.py
+file path=usr/lib/python3.5/email/architecture.rst
+file path=usr/lib/python3.5/email/base64mime.py
+file path=usr/lib/python3.5/email/charset.py
+file path=usr/lib/python3.5/email/contentmanager.py
+file path=usr/lib/python3.5/email/encoders.py
+file path=usr/lib/python3.5/email/errors.py
+file path=usr/lib/python3.5/email/feedparser.py
+file path=usr/lib/python3.5/email/generator.py
+file path=usr/lib/python3.5/email/header.py
+file path=usr/lib/python3.5/email/headerregistry.py
+file path=usr/lib/python3.5/email/iterators.py
+file path=usr/lib/python3.5/email/message.py
+file path=usr/lib/python3.5/email/mime/__init__.py
+file path=usr/lib/python3.5/email/mime/application.py
+file path=usr/lib/python3.5/email/mime/audio.py
+file path=usr/lib/python3.5/email/mime/base.py
+file path=usr/lib/python3.5/email/mime/image.py
+file path=usr/lib/python3.5/email/mime/message.py
+file path=usr/lib/python3.5/email/mime/multipart.py
+file path=usr/lib/python3.5/email/mime/nonmultipart.py
+file path=usr/lib/python3.5/email/mime/text.py
+file path=usr/lib/python3.5/email/parser.py
+file path=usr/lib/python3.5/email/policy.py
+file path=usr/lib/python3.5/email/quoprimime.py
+file path=usr/lib/python3.5/email/utils.py
+file path=usr/lib/python3.5/encodings/__init__.py
+file path=usr/lib/python3.5/encodings/aliases.py
+file path=usr/lib/python3.5/encodings/ascii.py
+file path=usr/lib/python3.5/encodings/base64_codec.py
+file path=usr/lib/python3.5/encodings/big5.py
+file path=usr/lib/python3.5/encodings/big5hkscs.py
+file path=usr/lib/python3.5/encodings/bz2_codec.py
+file path=usr/lib/python3.5/encodings/charmap.py
+file path=usr/lib/python3.5/encodings/cp037.py
+file path=usr/lib/python3.5/encodings/cp1006.py
+file path=usr/lib/python3.5/encodings/cp1026.py
+file path=usr/lib/python3.5/encodings/cp1125.py
+file path=usr/lib/python3.5/encodings/cp1140.py
+file path=usr/lib/python3.5/encodings/cp1250.py
+file path=usr/lib/python3.5/encodings/cp1251.py
+file path=usr/lib/python3.5/encodings/cp1252.py
+file path=usr/lib/python3.5/encodings/cp1253.py
+file path=usr/lib/python3.5/encodings/cp1254.py
+file path=usr/lib/python3.5/encodings/cp1255.py
+file path=usr/lib/python3.5/encodings/cp1256.py
+file path=usr/lib/python3.5/encodings/cp1257.py
+file path=usr/lib/python3.5/encodings/cp1258.py
+file path=usr/lib/python3.5/encodings/cp273.py
+file path=usr/lib/python3.5/encodings/cp424.py
+file path=usr/lib/python3.5/encodings/cp437.py
+file path=usr/lib/python3.5/encodings/cp500.py
+file path=usr/lib/python3.5/encodings/cp65001.py
+file path=usr/lib/python3.5/encodings/cp720.py
+file path=usr/lib/python3.5/encodings/cp737.py
+file path=usr/lib/python3.5/encodings/cp775.py
+file path=usr/lib/python3.5/encodings/cp850.py
+file path=usr/lib/python3.5/encodings/cp852.py
+file path=usr/lib/python3.5/encodings/cp855.py
+file path=usr/lib/python3.5/encodings/cp856.py
+file path=usr/lib/python3.5/encodings/cp857.py
+file path=usr/lib/python3.5/encodings/cp858.py
+file path=usr/lib/python3.5/encodings/cp860.py
+file path=usr/lib/python3.5/encodings/cp861.py
+file path=usr/lib/python3.5/encodings/cp862.py
+file path=usr/lib/python3.5/encodings/cp863.py
+file path=usr/lib/python3.5/encodings/cp864.py
+file path=usr/lib/python3.5/encodings/cp865.py
+file path=usr/lib/python3.5/encodings/cp866.py
+file path=usr/lib/python3.5/encodings/cp869.py
+file path=usr/lib/python3.5/encodings/cp874.py
+file path=usr/lib/python3.5/encodings/cp875.py
+file path=usr/lib/python3.5/encodings/cp932.py
+file path=usr/lib/python3.5/encodings/cp949.py
+file path=usr/lib/python3.5/encodings/cp950.py
+file path=usr/lib/python3.5/encodings/euc_jis_2004.py
+file path=usr/lib/python3.5/encodings/euc_jisx0213.py
+file path=usr/lib/python3.5/encodings/euc_jp.py
+file path=usr/lib/python3.5/encodings/euc_kr.py
+file path=usr/lib/python3.5/encodings/gb18030.py
+file path=usr/lib/python3.5/encodings/gb2312.py
+file path=usr/lib/python3.5/encodings/gbk.py
+file path=usr/lib/python3.5/encodings/hex_codec.py
+file path=usr/lib/python3.5/encodings/hp_roman8.py
+file path=usr/lib/python3.5/encodings/hz.py
+file path=usr/lib/python3.5/encodings/idna.py
+file path=usr/lib/python3.5/encodings/iso2022_jp.py
+file path=usr/lib/python3.5/encodings/iso2022_jp_1.py
+file path=usr/lib/python3.5/encodings/iso2022_jp_2.py
+file path=usr/lib/python3.5/encodings/iso2022_jp_2004.py
+file path=usr/lib/python3.5/encodings/iso2022_jp_3.py
+file path=usr/lib/python3.5/encodings/iso2022_jp_ext.py
+file path=usr/lib/python3.5/encodings/iso2022_kr.py
+file path=usr/lib/python3.5/encodings/iso8859_1.py
+file path=usr/lib/python3.5/encodings/iso8859_10.py
+file path=usr/lib/python3.5/encodings/iso8859_11.py
+file path=usr/lib/python3.5/encodings/iso8859_13.py
+file path=usr/lib/python3.5/encodings/iso8859_14.py
+file path=usr/lib/python3.5/encodings/iso8859_15.py
+file path=usr/lib/python3.5/encodings/iso8859_16.py
+file path=usr/lib/python3.5/encodings/iso8859_2.py
+file path=usr/lib/python3.5/encodings/iso8859_3.py
+file path=usr/lib/python3.5/encodings/iso8859_4.py
+file path=usr/lib/python3.5/encodings/iso8859_5.py
+file path=usr/lib/python3.5/encodings/iso8859_6.py
+file path=usr/lib/python3.5/encodings/iso8859_7.py
+file path=usr/lib/python3.5/encodings/iso8859_8.py
+file path=usr/lib/python3.5/encodings/iso8859_9.py
+file path=usr/lib/python3.5/encodings/johab.py
+file path=usr/lib/python3.5/encodings/koi8_r.py
+file path=usr/lib/python3.5/encodings/koi8_t.py
+file path=usr/lib/python3.5/encodings/koi8_u.py
+file path=usr/lib/python3.5/encodings/kz1048.py
+file path=usr/lib/python3.5/encodings/latin_1.py
+file path=usr/lib/python3.5/encodings/mac_arabic.py
+file path=usr/lib/python3.5/encodings/mac_centeuro.py
+file path=usr/lib/python3.5/encodings/mac_croatian.py
+file path=usr/lib/python3.5/encodings/mac_cyrillic.py
+file path=usr/lib/python3.5/encodings/mac_farsi.py
+file path=usr/lib/python3.5/encodings/mac_greek.py
+file path=usr/lib/python3.5/encodings/mac_iceland.py
+file path=usr/lib/python3.5/encodings/mac_latin2.py
+file path=usr/lib/python3.5/encodings/mac_roman.py
+file path=usr/lib/python3.5/encodings/mac_romanian.py
+file path=usr/lib/python3.5/encodings/mac_turkish.py
+file path=usr/lib/python3.5/encodings/mbcs.py
+file path=usr/lib/python3.5/encodings/palmos.py
+file path=usr/lib/python3.5/encodings/ptcp154.py
+file path=usr/lib/python3.5/encodings/punycode.py
+file path=usr/lib/python3.5/encodings/quopri_codec.py
+file path=usr/lib/python3.5/encodings/raw_unicode_escape.py
+file path=usr/lib/python3.5/encodings/rot_13.py
+file path=usr/lib/python3.5/encodings/shift_jis.py
+file path=usr/lib/python3.5/encodings/shift_jis_2004.py
+file path=usr/lib/python3.5/encodings/shift_jisx0213.py
+file path=usr/lib/python3.5/encodings/tis_620.py
+file path=usr/lib/python3.5/encodings/undefined.py
+file path=usr/lib/python3.5/encodings/unicode_escape.py
+file path=usr/lib/python3.5/encodings/unicode_internal.py
+file path=usr/lib/python3.5/encodings/utf_16.py
+file path=usr/lib/python3.5/encodings/utf_16_be.py
+file path=usr/lib/python3.5/encodings/utf_16_le.py
+file path=usr/lib/python3.5/encodings/utf_32.py
+file path=usr/lib/python3.5/encodings/utf_32_be.py
+file path=usr/lib/python3.5/encodings/utf_32_le.py
+file path=usr/lib/python3.5/encodings/utf_7.py
+file path=usr/lib/python3.5/encodings/utf_8.py
+file path=usr/lib/python3.5/encodings/utf_8_sig.py
+file path=usr/lib/python3.5/encodings/uu_codec.py
+file path=usr/lib/python3.5/encodings/zlib_codec.py
+file path=usr/lib/python3.5/ensurepip/__init__.py
+file path=usr/lib/python3.5/ensurepip/__main__.py
+file path=usr/lib/python3.5/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl
+file path=usr/lib/python3.5/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl
+file path=usr/lib/python3.5/ensurepip/_uninstall.py
+file path=usr/lib/python3.5/enum.py
+file path=usr/lib/python3.5/filecmp.py
+file path=usr/lib/python3.5/fileinput.py
+file path=usr/lib/python3.5/fnmatch.py
+file path=usr/lib/python3.5/formatter.py
+file path=usr/lib/python3.5/fractions.py
+file path=usr/lib/python3.5/ftplib.py
+file path=usr/lib/python3.5/functools.py
+file path=usr/lib/python3.5/genericpath.py
+file path=usr/lib/python3.5/getopt.py
+file path=usr/lib/python3.5/getpass.py
+file path=usr/lib/python3.5/gettext.py
+file path=usr/lib/python3.5/glob.py
+file path=usr/lib/python3.5/gzip.py
+file path=usr/lib/python3.5/hashlib.py
+file path=usr/lib/python3.5/heapq.py
+file path=usr/lib/python3.5/hmac.py
+file path=usr/lib/python3.5/html/__init__.py
+file path=usr/lib/python3.5/html/entities.py
+file path=usr/lib/python3.5/html/parser.py
+file path=usr/lib/python3.5/http/__init__.py
+file path=usr/lib/python3.5/http/client.py
+file path=usr/lib/python3.5/http/cookiejar.py
+file path=usr/lib/python3.5/http/cookies.py
+file path=usr/lib/python3.5/http/server.py
+file path=usr/lib/python3.5/idlelib/AutoComplete.py
+file path=usr/lib/python3.5/idlelib/AutoCompleteWindow.py
+file path=usr/lib/python3.5/idlelib/AutoExpand.py
+file path=usr/lib/python3.5/idlelib/Bindings.py
+file path=usr/lib/python3.5/idlelib/CREDITS.txt
+file path=usr/lib/python3.5/idlelib/CallTipWindow.py
+file path=usr/lib/python3.5/idlelib/CallTips.py
+file path=usr/lib/python3.5/idlelib/ChangeLog
+file path=usr/lib/python3.5/idlelib/ClassBrowser.py
+file path=usr/lib/python3.5/idlelib/CodeContext.py
+file path=usr/lib/python3.5/idlelib/ColorDelegator.py
+file path=usr/lib/python3.5/idlelib/Debugger.py
+file path=usr/lib/python3.5/idlelib/Delegator.py
+file path=usr/lib/python3.5/idlelib/EditorWindow.py
+file path=usr/lib/python3.5/idlelib/FileList.py
+file path=usr/lib/python3.5/idlelib/FormatParagraph.py
+file path=usr/lib/python3.5/idlelib/GrepDialog.py
+file path=usr/lib/python3.5/idlelib/HISTORY.txt
+file path=usr/lib/python3.5/idlelib/HyperParser.py
+file path=usr/lib/python3.5/idlelib/IOBinding.py
+file path=usr/lib/python3.5/idlelib/Icons/folder.gif
+file path=usr/lib/python3.5/idlelib/Icons/idle.icns
+file path=usr/lib/python3.5/idlelib/Icons/idle.ico
+file path=usr/lib/python3.5/idlelib/Icons/idle_16.gif
+file path=usr/lib/python3.5/idlelib/Icons/idle_16.png
+file path=usr/lib/python3.5/idlelib/Icons/idle_32.gif
+file path=usr/lib/python3.5/idlelib/Icons/idle_32.png
+file path=usr/lib/python3.5/idlelib/Icons/idle_48.gif
+file path=usr/lib/python3.5/idlelib/Icons/idle_48.png
+file path=usr/lib/python3.5/idlelib/Icons/minusnode.gif
+file path=usr/lib/python3.5/idlelib/Icons/openfolder.gif
+file path=usr/lib/python3.5/idlelib/Icons/plusnode.gif
+file path=usr/lib/python3.5/idlelib/Icons/python.gif
+file path=usr/lib/python3.5/idlelib/Icons/tk.gif
+file path=usr/lib/python3.5/idlelib/IdleHistory.py
+file path=usr/lib/python3.5/idlelib/MultiCall.py
+file path=usr/lib/python3.5/idlelib/MultiStatusBar.py
+file path=usr/lib/python3.5/idlelib/NEWS.txt
+file path=usr/lib/python3.5/idlelib/ObjectBrowser.py
+file path=usr/lib/python3.5/idlelib/OutputWindow.py
+file path=usr/lib/python3.5/idlelib/ParenMatch.py
+file path=usr/lib/python3.5/idlelib/PathBrowser.py
+file path=usr/lib/python3.5/idlelib/Percolator.py
+file path=usr/lib/python3.5/idlelib/PyParse.py
+file path=usr/lib/python3.5/idlelib/PyShell.py
+file path=usr/lib/python3.5/idlelib/README.txt
+file path=usr/lib/python3.5/idlelib/RemoteDebugger.py
+file path=usr/lib/python3.5/idlelib/RemoteObjectBrowser.py
+file path=usr/lib/python3.5/idlelib/ReplaceDialog.py
+file path=usr/lib/python3.5/idlelib/RstripExtension.py
+file path=usr/lib/python3.5/idlelib/ScriptBinding.py
+file path=usr/lib/python3.5/idlelib/ScrolledList.py
+file path=usr/lib/python3.5/idlelib/SearchDialog.py
+file path=usr/lib/python3.5/idlelib/SearchDialogBase.py
+file path=usr/lib/python3.5/idlelib/SearchEngine.py
+file path=usr/lib/python3.5/idlelib/StackViewer.py
+file path=usr/lib/python3.5/idlelib/TODO.txt
+file path=usr/lib/python3.5/idlelib/ToolTip.py
+file path=usr/lib/python3.5/idlelib/TreeWidget.py
+file path=usr/lib/python3.5/idlelib/UndoDelegator.py
+file path=usr/lib/python3.5/idlelib/WidgetRedirector.py
+file path=usr/lib/python3.5/idlelib/WindowList.py
+file path=usr/lib/python3.5/idlelib/ZoomHeight.py
+file path=usr/lib/python3.5/idlelib/__init__.py
+file path=usr/lib/python3.5/idlelib/__main__.py
+file path=usr/lib/python3.5/idlelib/aboutDialog.py
+file path=usr/lib/python3.5/idlelib/config-extensions.def
+file path=usr/lib/python3.5/idlelib/config-highlight.def
+file path=usr/lib/python3.5/idlelib/config-keys.def
+file path=usr/lib/python3.5/idlelib/config-main.def
+file path=usr/lib/python3.5/idlelib/configDialog.py
+file path=usr/lib/python3.5/idlelib/configHandler.py
+file path=usr/lib/python3.5/idlelib/configHelpSourceEdit.py
+file path=usr/lib/python3.5/idlelib/configSectionNameDialog.py
+file path=usr/lib/python3.5/idlelib/dynOptionMenuWidget.py
+file path=usr/lib/python3.5/idlelib/extend.txt
+file path=usr/lib/python3.5/idlelib/help.txt
+file path=usr/lib/python3.5/idlelib/idle.bat
+file path=usr/lib/python3.5/idlelib/idle.py
+file path=usr/lib/python3.5/idlelib/idle.pyw
+file path=usr/lib/python3.5/idlelib/idle_test/README.txt
+file path=usr/lib/python3.5/idlelib/idle_test/__init__.py
+file path=usr/lib/python3.5/idlelib/idle_test/htest.py
+file path=usr/lib/python3.5/idlelib/idle_test/mock_idle.py
+file path=usr/lib/python3.5/idlelib/idle_test/mock_tk.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_autocomplete.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_autoexpand.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_calltips.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_config_name.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_configdialog.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_delegator.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_editor.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_formatparagraph.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_grep.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_hyperparser.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_idlehistory.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_io.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_parenmatch.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_pathbrowser.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_rstrip.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_searchdialogbase.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_searchengine.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_text.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_textview.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_warning.py
+file path=usr/lib/python3.5/idlelib/idle_test/test_widgetredir.py
+file path=usr/lib/python3.5/idlelib/idlever.py
+file path=usr/lib/python3.5/idlelib/keybindingDialog.py
+file path=usr/lib/python3.5/idlelib/macosxSupport.py
+file path=usr/lib/python3.5/idlelib/rpc.py
+file path=usr/lib/python3.5/idlelib/run.py
+file path=usr/lib/python3.5/idlelib/tabbedpages.py
+file path=usr/lib/python3.5/idlelib/textView.py
+file path=usr/lib/python3.5/imaplib.py
+file path=usr/lib/python3.5/imghdr.py
+file path=usr/lib/python3.5/imp.py
+file path=usr/lib/python3.5/importlib/__init__.py
+file path=usr/lib/python3.5/importlib/_bootstrap.py
+file path=usr/lib/python3.5/importlib/_bootstrap_external.py
+file path=usr/lib/python3.5/importlib/abc.py
+file path=usr/lib/python3.5/importlib/machinery.py
+file path=usr/lib/python3.5/importlib/util.py
+file path=usr/lib/python3.5/inspect.py
+file path=usr/lib/python3.5/io.py
+file path=usr/lib/python3.5/ipaddress.py
+file path=usr/lib/python3.5/json/__init__.py
+file path=usr/lib/python3.5/json/decoder.py
+file path=usr/lib/python3.5/json/encoder.py
+file path=usr/lib/python3.5/json/scanner.py
+file path=usr/lib/python3.5/json/tool.py
+file path=usr/lib/python3.5/keyword.py
+file path=usr/lib/python3.5/lib-dynload/_bisect.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_bz2.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_cn.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_hk.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_iso2022.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_jp.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_kr.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_codecs_tw.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_crypt.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_csv.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_ctypes.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_ctypes_test.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_curses.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_curses_panel.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_datetime.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_dbm.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_decimal.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_elementtree.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_gdbm.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_hashlib.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_heapq.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_json.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_lsprof.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_lzma.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_md5.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_multibytecodec.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_multiprocessing.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_opcode.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_pickle.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_posixsubprocess.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_random.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_sha1.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_sha256.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_sha512.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_socket.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_sqlite3.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_ssl.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_struct.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_testbuffer.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_testcapi.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_testimportmultiple.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/_testmultiphase.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/array.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/audioop.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/binascii.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/cmath.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/dlpi.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/fcntl.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/grp.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/math.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/mmap.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/nis.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/ossaudiodev.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/parser.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/privileges.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/pyexpat.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/rbac.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/readline.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/resource.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/select.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/spwd.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/syslog.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/termios.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/ucred.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/unicodedata.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/xxlimited.cpython-35m.so
+file path=usr/lib/python3.5/lib-dynload/zlib.cpython-35m.so
+file path=usr/lib/python3.5/lib2to3/Grammar.txt
+file path=usr/lib/python3.5/lib2to3/Grammar3.5.0.final.0.pickle
+file path=usr/lib/python3.5/lib2to3/PatternGrammar.txt
+file path=usr/lib/python3.5/lib2to3/PatternGrammar3.5.0.final.0.pickle
+file path=usr/lib/python3.5/lib2to3/__init__.py
+file path=usr/lib/python3.5/lib2to3/__main__.py
+file path=usr/lib/python3.5/lib2to3/btm_matcher.py
+file path=usr/lib/python3.5/lib2to3/btm_utils.py
+file path=usr/lib/python3.5/lib2to3/fixer_base.py
+file path=usr/lib/python3.5/lib2to3/fixer_util.py
+file path=usr/lib/python3.5/lib2to3/fixes/__init__.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_apply.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_asserts.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_basestring.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_buffer.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_callable.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_dict.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_except.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_exec.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_execfile.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_exitfunc.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_filter.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_funcattrs.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_future.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_getcwdu.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_has_key.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_idioms.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_import.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_imports.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_imports2.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_input.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_intern.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_isinstance.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_itertools.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_itertools_imports.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_long.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_map.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_metaclass.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_methodattrs.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_ne.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_next.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_nonzero.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_numliterals.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_operator.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_paren.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_print.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_raise.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_raw_input.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_reduce.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_reload.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_renames.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_repr.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_set_literal.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_standarderror.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_sys_exc.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_throw.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_tuple_params.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_types.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_unicode.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_urllib.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_ws_comma.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_xrange.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_xreadlines.py
+file path=usr/lib/python3.5/lib2to3/fixes/fix_zip.py
+file path=usr/lib/python3.5/lib2to3/main.py
+file path=usr/lib/python3.5/lib2to3/patcomp.py
+file path=usr/lib/python3.5/lib2to3/pgen2/__init__.py
+file path=usr/lib/python3.5/lib2to3/pgen2/conv.py
+file path=usr/lib/python3.5/lib2to3/pgen2/driver.py
+file path=usr/lib/python3.5/lib2to3/pgen2/grammar.py
+file path=usr/lib/python3.5/lib2to3/pgen2/literals.py
+file path=usr/lib/python3.5/lib2to3/pgen2/parse.py
+file path=usr/lib/python3.5/lib2to3/pgen2/pgen.py
+file path=usr/lib/python3.5/lib2to3/pgen2/token.py
+file path=usr/lib/python3.5/lib2to3/pgen2/tokenize.py
+file path=usr/lib/python3.5/lib2to3/pygram.py
+file path=usr/lib/python3.5/lib2to3/pytree.py
+file path=usr/lib/python3.5/lib2to3/refactor.py
+file path=usr/lib/python3.5/lib2to3/tests/__init__.py
+file path=usr/lib/python3.5/lib2to3/tests/__main__.py
+file path=usr/lib/python3.5/lib2to3/tests/data/README
+file path=usr/lib/python3.5/lib2to3/tests/data/bom.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/crlf.py pkg.tmp.autopyc=false
+#
+# The {different,false}_encoding.py files needs bypass-generate because they
+# contains an intentional SyntaxError with a invalid string that cannot be
+# parsed.
+#
+file path=usr/lib/python3.5/lib2to3/tests/data/different_encoding.py \
+ pkg.depend.bypass-generate=.* pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/false_encoding.py \
+ pkg.depend.bypass-generate=.* pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/bad_order.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/__init__.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/fix_explicit.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/fix_first.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/fix_last.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/fix_parrot.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/myfixes/fix_preorder.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/no_fixer_cls.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/fixers/parrot_example.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/infinite_recursion.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/py2_test_grammar.py \
+ pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/lib2to3/tests/data/py3_test_grammar.py \
+ pkg.tmp.autopyc=false
+#
+# bypass-generate needed due to issue with __main__.
+#
+file path=usr/lib/python3.5/lib2to3/tests/pytree_idempotency.py \
+ pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/lib2to3/tests/support.py
+file path=usr/lib/python3.5/lib2to3/tests/test_all_fixers.py
+file path=usr/lib/python3.5/lib2to3/tests/test_fixers.py
+file path=usr/lib/python3.5/lib2to3/tests/test_main.py
+file path=usr/lib/python3.5/lib2to3/tests/test_parser.py
+file path=usr/lib/python3.5/lib2to3/tests/test_pytree.py
+file path=usr/lib/python3.5/lib2to3/tests/test_refactor.py
+file path=usr/lib/python3.5/lib2to3/tests/test_util.py
+file path=usr/lib/python3.5/linecache.py
+file path=usr/lib/python3.5/locale.py
+file path=usr/lib/python3.5/logging/__init__.py
+file path=usr/lib/python3.5/logging/config.py
+file path=usr/lib/python3.5/logging/handlers.py
+file path=usr/lib/python3.5/lzma.py
+file path=usr/lib/python3.5/macpath.py
+file path=usr/lib/python3.5/macurl2path.py
+file path=usr/lib/python3.5/mailbox.py
+file path=usr/lib/python3.5/mailcap.py
+file path=usr/lib/python3.5/mimetypes.py
+file path=usr/lib/python3.5/modulefinder.py
+file path=usr/lib/python3.5/multiprocessing/__init__.py
+file path=usr/lib/python3.5/multiprocessing/connection.py
+file path=usr/lib/python3.5/multiprocessing/context.py
+file path=usr/lib/python3.5/multiprocessing/dummy/__init__.py
+file path=usr/lib/python3.5/multiprocessing/dummy/connection.py
+file path=usr/lib/python3.5/multiprocessing/forkserver.py
+file path=usr/lib/python3.5/multiprocessing/heap.py
+file path=usr/lib/python3.5/multiprocessing/managers.py
+file path=usr/lib/python3.5/multiprocessing/pool.py
+file path=usr/lib/python3.5/multiprocessing/popen_fork.py
+file path=usr/lib/python3.5/multiprocessing/popen_forkserver.py
+file path=usr/lib/python3.5/multiprocessing/popen_spawn_posix.py
+file path=usr/lib/python3.5/multiprocessing/popen_spawn_win32.py
+file path=usr/lib/python3.5/multiprocessing/process.py
+file path=usr/lib/python3.5/multiprocessing/queues.py
+file path=usr/lib/python3.5/multiprocessing/reduction.py
+file path=usr/lib/python3.5/multiprocessing/resource_sharer.py
+file path=usr/lib/python3.5/multiprocessing/semaphore_tracker.py
+file path=usr/lib/python3.5/multiprocessing/sharedctypes.py
+file path=usr/lib/python3.5/multiprocessing/spawn.py
+file path=usr/lib/python3.5/multiprocessing/synchronize.py
+file path=usr/lib/python3.5/multiprocessing/util.py
+file path=usr/lib/python3.5/netrc.py
+file path=usr/lib/python3.5/nntplib.py
+file path=usr/lib/python3.5/ntpath.py
+file path=usr/lib/python3.5/nturl2path.py
+file path=usr/lib/python3.5/numbers.py
+file path=usr/lib/python3.5/opcode.py
+file path=usr/lib/python3.5/operator.py
+file path=usr/lib/python3.5/optparse.py
+file path=usr/lib/python3.5/os.py
+file path=usr/lib/python3.5/pathlib.py
+file path=usr/lib/python3.5/pdb.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/pickle.py
+file path=usr/lib/python3.5/pickletools.py
+file path=usr/lib/python3.5/pipes.py
+file path=usr/lib/python3.5/pkgutil.py
+file path=usr/lib/python3.5/plat-sunos5/CDIO.py
+file path=usr/lib/python3.5/plat-sunos5/DLFCN.py
+file path=usr/lib/python3.5/plat-sunos5/IN.py
+file path=usr/lib/python3.5/plat-sunos5/STROPTS.py
+file path=usr/lib/python3.5/plat-sunos5/TYPES.py
+file path=usr/lib/python3.5/plat-sunos5/regen
+# XXX bootstrap
+#file path=usr/lib/python3.5/platform.py
+# pkg.depend.bypass-generate=.*/MacOS.*
+# pkg.depend.bypass-generate=.*/_gestalt.*
+# pkg.depend.bypass-generate=.*/java/__init__.py
+# pkg.depend.bypass-generate=.*/lang.*
+# pkg.depend.bypass-generate=.*/vms_lib.*
+# pkg.depend.bypass-generate=.*/win32api.*
+# pkg.depend.bypass-generate=.*/win32con.*
+# pkg.depend.bypass-generate=.*/winreg.*
+file path=usr/lib/python3.5/platform.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/plistlib.py
+file path=usr/lib/python3.5/poplib.py
+file path=usr/lib/python3.5/posixpath.py
+file path=usr/lib/python3.5/pprint.py
+file path=usr/lib/python3.5/profile.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/pstats.py
+file path=usr/lib/python3.5/pty.py
+file path=usr/lib/python3.5/py_compile.py
+file path=usr/lib/python3.5/pyclbr.py
+file path=usr/lib/python3.5/pydoc.py
+file path=usr/lib/python3.5/pydoc_data/__init__.py
+file path=usr/lib/python3.5/pydoc_data/_pydoc.css
+file path=usr/lib/python3.5/pydoc_data/topics.py
+file path=usr/lib/python3.5/queue.py
+file path=usr/lib/python3.5/quopri.py
+file path=usr/lib/python3.5/random.py
+file path=usr/lib/python3.5/re.py
+file path=usr/lib/python3.5/reprlib.py
+file path=usr/lib/python3.5/rlcompleter.py
+file path=usr/lib/python3.5/runpy.py
+file path=usr/lib/python3.5/sched.py
+file path=usr/lib/python3.5/selectors.py
+file path=usr/lib/python3.5/shelve.py
+file path=usr/lib/python3.5/shlex.py
+file path=usr/lib/python3.5/shutil.py
+file path=usr/lib/python3.5/signal.py
+file path=usr/lib/python3.5/site-packages/README
+file path=usr/lib/python3.5/site-packages/vendor-packages.pth
+file path=usr/lib/python3.5/site.py
+file path=usr/lib/python3.5/smtpd.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/smtplib.py
+file path=usr/lib/python3.5/sndhdr.py
+file path=usr/lib/python3.5/socket.py
+file path=usr/lib/python3.5/socketserver.py
+file path=usr/lib/python3.5/sqlite3/__init__.py
+file path=usr/lib/python3.5/sqlite3/dbapi2.py
+file path=usr/lib/python3.5/sqlite3/dump.py
+file path=usr/lib/python3.5/sqlite3/test/__init__.py
+file path=usr/lib/python3.5/sqlite3/test/dbapi.py
+file path=usr/lib/python3.5/sqlite3/test/dump.py
+file path=usr/lib/python3.5/sqlite3/test/factory.py
+file path=usr/lib/python3.5/sqlite3/test/hooks.py
+file path=usr/lib/python3.5/sqlite3/test/regression.py
+file path=usr/lib/python3.5/sqlite3/test/transactions.py
+file path=usr/lib/python3.5/sqlite3/test/types.py
+file path=usr/lib/python3.5/sqlite3/test/userfunctions.py
+file path=usr/lib/python3.5/sre_compile.py
+file path=usr/lib/python3.5/sre_constants.py
+file path=usr/lib/python3.5/sre_parse.py
+file path=usr/lib/python3.5/ssl.py
+file path=usr/lib/python3.5/stat.py
+file path=usr/lib/python3.5/statistics.py
+file path=usr/lib/python3.5/string.py
+file path=usr/lib/python3.5/stringprep.py
+file path=usr/lib/python3.5/struct.py
+file path=usr/lib/python3.5/subprocess.py
+file path=usr/lib/python3.5/sunau.py
+file path=usr/lib/python3.5/symbol.py
+file path=usr/lib/python3.5/symtable.py
+file path=usr/lib/python3.5/sysconfig.py
+file path=usr/lib/python3.5/tabnanny.py
+file path=usr/lib/python3.5/tarfile.py
+file path=usr/lib/python3.5/telnetlib.py
+file path=usr/lib/python3.5/tempfile.py
+file path=usr/lib/python3.5/test/185test.db
+file path=usr/lib/python3.5/test/Sine-1000Hz-300ms.aif
+file path=usr/lib/python3.5/test/__init__.py
+file path=usr/lib/python3.5/test/__main__.py
+file path=usr/lib/python3.5/test/_test_multiprocessing.py
+file path=usr/lib/python3.5/test/audiodata/pluck-alaw.aifc
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm16.aiff
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm16.au
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm16.wav
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm24.aiff
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm24.au
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm24.wav
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm32.aiff
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm32.au
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm32.wav
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm8.aiff
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm8.au
+file path=usr/lib/python3.5/test/audiodata/pluck-pcm8.wav
+file path=usr/lib/python3.5/test/audiodata/pluck-ulaw.aifc
+file path=usr/lib/python3.5/test/audiodata/pluck-ulaw.au
+file path=usr/lib/python3.5/test/audiotest.au
+file path=usr/lib/python3.5/test/audiotests.py
+file path=usr/lib/python3.5/test/autotest.py
+file path=usr/lib/python3.5/test/bad_coding.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/bad_coding2.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badcert.pem
+file path=usr/lib/python3.5/test/badkey.pem
+file path=usr/lib/python3.5/test/badsyntax_3131.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future10.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future3.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future4.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future5.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future6.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future7.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future8.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_future9.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/badsyntax_pep3120.py pkg.tmp.autopyc=false
+file path=usr/lib/python3.5/test/buffer_tests.py
+file path=usr/lib/python3.5/test/bytecode_helper.py
+file path=usr/lib/python3.5/test/capath/4e1295a3.0
+file path=usr/lib/python3.5/test/capath/5ed36f99.0
+file path=usr/lib/python3.5/test/capath/6e88d7b8.0
+file path=usr/lib/python3.5/test/capath/99d0fa06.0
+file path=usr/lib/python3.5/test/cfgparser.1
+file path=usr/lib/python3.5/test/cfgparser.2
+file path=usr/lib/python3.5/test/cfgparser.3
+file path=usr/lib/python3.5/test/check_soundcard.vbs
+file path=usr/lib/python3.5/test/cjkencodings/big5-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/big5.txt
+file path=usr/lib/python3.5/test/cjkencodings/big5hkscs-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/big5hkscs.txt
+file path=usr/lib/python3.5/test/cjkencodings/cp949-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/cp949.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_jisx0213-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_jisx0213.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_jp-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_jp.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_kr-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/euc_kr.txt
+file path=usr/lib/python3.5/test/cjkencodings/gb18030-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/gb18030.txt
+file path=usr/lib/python3.5/test/cjkencodings/gb2312-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/gb2312.txt
+file path=usr/lib/python3.5/test/cjkencodings/gbk-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/gbk.txt
+file path=usr/lib/python3.5/test/cjkencodings/hz-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/hz.txt
+file path=usr/lib/python3.5/test/cjkencodings/iso2022_jp-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/iso2022_jp.txt
+file path=usr/lib/python3.5/test/cjkencodings/iso2022_kr-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/iso2022_kr.txt
+file path=usr/lib/python3.5/test/cjkencodings/johab-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/johab.txt
+file path=usr/lib/python3.5/test/cjkencodings/shift_jis-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/shift_jis.txt
+file path=usr/lib/python3.5/test/cjkencodings/shift_jisx0213-utf8.txt
+file path=usr/lib/python3.5/test/cjkencodings/shift_jisx0213.txt
+file path=usr/lib/python3.5/test/cmath_testcases.txt
+file path=usr/lib/python3.5/test/coding20731.py
+file path=usr/lib/python3.5/test/curses_tests.py
+file path=usr/lib/python3.5/test/data/README
+file path=usr/lib/python3.5/test/datetimetester.py
+file path=usr/lib/python3.5/test/decimaltestdata/abs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/add.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/and.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/base.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/clamp.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/class.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/compare.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/comparetotal.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/comparetotmag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/copy.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/copyabs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/copynegate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/copysign.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddAbs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddAdd.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddAnd.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddBase.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCanonical.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddClass.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCompare.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCompareSig.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCompareTotal.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCompareTotalMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCopy.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCopyAbs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCopyNegate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddCopySign.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddDivide.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddDivideInt.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddEncode.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddFMA.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddInvert.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddLogB.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMax.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMaxMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMin.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMinMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMinus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddMultiply.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddNextMinus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddNextPlus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddNextToward.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddOr.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddPlus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddQuantize.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddReduce.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddRemainder.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddRemainderNear.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddRotate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddSameQuantum.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddScaleB.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddShift.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddSubtract.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddToIntegral.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ddXor.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/decDouble.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/decQuad.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/decSingle.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/divide.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/divideint.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqAbs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqAdd.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqAnd.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqBase.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCanonical.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqClass.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCompare.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCompareSig.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCompareTotal.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCompareTotalMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCopy.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCopyAbs.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCopyNegate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqCopySign.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqDivide.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqDivideInt.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqEncode.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqFMA.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqInvert.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqLogB.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMax.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMaxMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMin.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMinMag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMinus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqMultiply.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqNextMinus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqNextPlus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqNextToward.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqOr.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqPlus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqQuantize.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqReduce.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqRemainder.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqRemainderNear.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqRotate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqSameQuantum.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqScaleB.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqShift.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqSubtract.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqToIntegral.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dqXor.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dsBase.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/dsEncode.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/exp.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/extra.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/fma.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/inexact.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/invert.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/ln.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/log10.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/logb.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/max.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/maxmag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/min.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/minmag.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/minus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/multiply.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/nextminus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/nextplus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/nexttoward.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/or.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/plus.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/power.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/powersqrt.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/quantize.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/randomBound32.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/randoms.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/reduce.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/remainder.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/remainderNear.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/rescale.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/rotate.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/rounding.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/samequantum.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/scaleb.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/shift.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/squareroot.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/subtract.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/testall.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/tointegral.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/tointegralx.decTest
+file path=usr/lib/python3.5/test/decimaltestdata/xor.decTest
+file path=usr/lib/python3.5/test/dh1024.pem
+file path=usr/lib/python3.5/test/dis_module.py
+file path=usr/lib/python3.5/test/dlpitest.py
+file path=usr/lib/python3.5/test/doctest_aliases.py
+file path=usr/lib/python3.5/test/double_const.py
+file path=usr/lib/python3.5/test/dtrace_sample.py
+file path=usr/lib/python3.5/test/eintrdata/eintr_tester.py
+file path=usr/lib/python3.5/test/empty.vbs
+file path=usr/lib/python3.5/test/encoded_modules/__init__.py
+file path=usr/lib/python3.5/test/encoded_modules/module_iso_8859_1.py
+file path=usr/lib/python3.5/test/encoded_modules/module_koi8_r.py
+file path=usr/lib/python3.5/test/exception_hierarchy.txt
+file path=usr/lib/python3.5/test/final_a.py
+file path=usr/lib/python3.5/test/final_b.py
+file path=usr/lib/python3.5/test/floating_points.txt
+file path=usr/lib/python3.5/test/fork_wait.py
+file path=usr/lib/python3.5/test/formatfloat_testcases.txt
+file path=usr/lib/python3.5/test/future_test1.py
+file path=usr/lib/python3.5/test/future_test2.py
+file path=usr/lib/python3.5/test/gdb_sample.py
+file path=usr/lib/python3.5/test/https_svn_python_org_root.pem
+file path=usr/lib/python3.5/test/ieee754.txt
+file path=usr/lib/python3.5/test/imghdrdata/python.bmp
+file path=usr/lib/python3.5/test/imghdrdata/python.exr
+file path=usr/lib/python3.5/test/imghdrdata/python.gif
+file path=usr/lib/python3.5/test/imghdrdata/python.jpg
+file path=usr/lib/python3.5/test/imghdrdata/python.pbm
+file path=usr/lib/python3.5/test/imghdrdata/python.pgm
+file path=usr/lib/python3.5/test/imghdrdata/python.png
+file path=usr/lib/python3.5/test/imghdrdata/python.ppm
+file path=usr/lib/python3.5/test/imghdrdata/python.ras
+file path=usr/lib/python3.5/test/imghdrdata/python.sgi
+file path=usr/lib/python3.5/test/imghdrdata/python.tiff
+file path=usr/lib/python3.5/test/imghdrdata/python.webp
+file path=usr/lib/python3.5/test/imghdrdata/python.xbm
+file path=usr/lib/python3.5/test/inspect_fodder.py
+file path=usr/lib/python3.5/test/inspect_fodder2.py
+file path=usr/lib/python3.5/test/keycert.passwd.pem
+file path=usr/lib/python3.5/test/keycert.pem
+file path=usr/lib/python3.5/test/keycert2.pem
+file path=usr/lib/python3.5/test/keycert3.pem
+file path=usr/lib/python3.5/test/keycert4.pem
+file path=usr/lib/python3.5/test/list_tests.py
+file path=usr/lib/python3.5/test/lock_tests.py
+file path=usr/lib/python3.5/test/mailcap.txt
+file path=usr/lib/python3.5/test/make_ssl_certs.py
+file path=usr/lib/python3.5/test/mapping_tests.py
+file path=usr/lib/python3.5/test/math_testcases.txt
+file path=usr/lib/python3.5/test/memory_watchdog.py
+file path=usr/lib/python3.5/test/mime.types
+file path=usr/lib/python3.5/test/mock_socket.py
+file path=usr/lib/python3.5/test/mp_fork_bomb.py
+file path=usr/lib/python3.5/test/multibytecodec_support.py
+file path=usr/lib/python3.5/test/nokia.pem
+file path=usr/lib/python3.5/test/nullbytecert.pem
+file path=usr/lib/python3.5/test/nullcert.pem
+file path=usr/lib/python3.5/test/outstanding_bugs.py
+file path=usr/lib/python3.5/test/pickletester.py
+file path=usr/lib/python3.5/test/privrbactest.py
+file path=usr/lib/python3.5/test/profilee.py
+file path=usr/lib/python3.5/test/pstats.pck
+file path=usr/lib/python3.5/test/pycacert.pem
+file path=usr/lib/python3.5/test/pycakey.pem
+file path=usr/lib/python3.5/test/pyclbr_input.py
+file path=usr/lib/python3.5/test/pydoc_mod.py
+file path=usr/lib/python3.5/test/pydocfodder.py
+file path=usr/lib/python3.5/test/pystone.py
+file path=usr/lib/python3.5/test/randv2_32.pck
+file path=usr/lib/python3.5/test/randv2_64.pck
+file path=usr/lib/python3.5/test/randv3.pck
+file path=usr/lib/python3.5/test/re_tests.py
+# XXX bootstrap
+# file path=usr/lib/python3.5/test/regrtest.py
+# pkg.depend.bypass-generate=.*/msvcrt.*
+file path=usr/lib/python3.5/test/regrtest.py pkg.depend.bypass-generate=.*
+file path=usr/lib/python3.5/test/relimport.py
+file path=usr/lib/python3.5/test/reperf.py
+file path=usr/lib/python3.5/test/revocation.crl
+file path=usr/lib/python3.5/test/sample_doctest.py
+file path=usr/lib/python3.5/test/sample_doctest_no_docstrings.py
+file path=usr/lib/python3.5/test/sample_doctest_no_doctests.py
+file path=usr/lib/python3.5/test/selfsigned_pythontestdotnet.pem
+file path=usr/lib/python3.5/test/seq_tests.py
+file path=usr/lib/python3.5/test/sgml_input.html
+file path=usr/lib/python3.5/test/sha256.pem
+file path=usr/lib/python3.5/test/sndhdrdata/README
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.8svx
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.aifc
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.aiff
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.au
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.hcom
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.sndt
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.voc
+file path=usr/lib/python3.5/test/sndhdrdata/sndhdr.wav
+file path=usr/lib/python3.5/test/sortperf.py
+file path=usr/lib/python3.5/test/ssl_cert.pem
+file path=usr/lib/python3.5/test/ssl_key.passwd.pem
+file path=usr/lib/python3.5/test/ssl_key.pem
+file path=usr/lib/python3.5/test/ssl_servers.py
+file path=usr/lib/python3.5/test/ssltests.py
+file path=usr/lib/python3.5/test/string_tests.py
+file path=usr/lib/python3.5/test/subprocessdata/fd_status.py
+file path=usr/lib/python3.5/test/subprocessdata/input_reader.py
+file path=usr/lib/python3.5/test/subprocessdata/qcat.py
+file path=usr/lib/python3.5/test/subprocessdata/qgrep.py
+file path=usr/lib/python3.5/test/subprocessdata/sigchild_ignore.py
+file path=usr/lib/python3.5/test/support/__init__.py
+file path=usr/lib/python3.5/test/support/script_helper.py
+file path=usr/lib/python3.5/test/test___all__.py
+file path=usr/lib/python3.5/test/test___future__.py
+file path=usr/lib/python3.5/test/test__locale.py
+file path=usr/lib/python3.5/test/test__opcode.py
+file path=usr/lib/python3.5/test/test__osx_support.py
+file path=usr/lib/python3.5/test/test_abc.py
+file path=usr/lib/python3.5/test/test_abstract_numbers.py
+file path=usr/lib/python3.5/test/test_aifc.py
+file path=usr/lib/python3.5/test/test_argparse.py
+file path=usr/lib/python3.5/test/test_array.py
+file path=usr/lib/python3.5/test/test_asdl_parser.py
+file path=usr/lib/python3.5/test/test_ast.py
+file path=usr/lib/python3.5/test/test_asynchat.py
+file path=usr/lib/python3.5/test/test_asyncio/__init__.py
+file path=usr/lib/python3.5/test/test_asyncio/__main__.py
+file path=usr/lib/python3.5/test/test_asyncio/echo.py
+file path=usr/lib/python3.5/test/test_asyncio/echo2.py
+file path=usr/lib/python3.5/test/test_asyncio/echo3.py
+file path=usr/lib/python3.5/test/test_asyncio/keycert3.pem
+file path=usr/lib/python3.5/test/test_asyncio/pycacert.pem
+file path=usr/lib/python3.5/test/test_asyncio/ssl_cert.pem
+file path=usr/lib/python3.5/test/test_asyncio/ssl_key.pem
+file path=usr/lib/python3.5/test/test_asyncio/test_base_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_futures.py
+file path=usr/lib/python3.5/test/test_asyncio/test_locks.py
+file path=usr/lib/python3.5/test/test_asyncio/test_pep492.py
+file path=usr/lib/python3.5/test/test_asyncio/test_proactor_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_queues.py
+file path=usr/lib/python3.5/test/test_asyncio/test_selector_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_sslproto.py
+file path=usr/lib/python3.5/test/test_asyncio/test_streams.py
+file path=usr/lib/python3.5/test/test_asyncio/test_subprocess.py
+file path=usr/lib/python3.5/test/test_asyncio/test_tasks.py
+file path=usr/lib/python3.5/test/test_asyncio/test_transports.py
+file path=usr/lib/python3.5/test/test_asyncio/test_unix_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_windows_events.py
+file path=usr/lib/python3.5/test/test_asyncio/test_windows_utils.py
+file path=usr/lib/python3.5/test/test_asyncore.py
+file path=usr/lib/python3.5/test/test_atexit.py
+file path=usr/lib/python3.5/test/test_audioop.py
+file path=usr/lib/python3.5/test/test_augassign.py
+file path=usr/lib/python3.5/test/test_base64.py
+file path=usr/lib/python3.5/test/test_bigaddrspace.py
+file path=usr/lib/python3.5/test/test_bigmem.py
+file path=usr/lib/python3.5/test/test_binascii.py
+file path=usr/lib/python3.5/test/test_binhex.py
+file path=usr/lib/python3.5/test/test_binop.py
+file path=usr/lib/python3.5/test/test_bisect.py
+file path=usr/lib/python3.5/test/test_bool.py
+file path=usr/lib/python3.5/test/test_buffer.py
+file path=usr/lib/python3.5/test/test_bufio.py
+file path=usr/lib/python3.5/test/test_builtin.py
+file path=usr/lib/python3.5/test/test_bytes.py
+file path=usr/lib/python3.5/test/test_bz2.py
+file path=usr/lib/python3.5/test/test_calendar.py
+file path=usr/lib/python3.5/test/test_call.py
+file path=usr/lib/python3.5/test/test_capi.py
+file path=usr/lib/python3.5/test/test_cgi.py
+file path=usr/lib/python3.5/test/test_cgitb.py
+file path=usr/lib/python3.5/test/test_charmapcodec.py
+file path=usr/lib/python3.5/test/test_class.py
+file path=usr/lib/python3.5/test/test_cmath.py
+file path=usr/lib/python3.5/test/test_cmd.py
+file path=usr/lib/python3.5/test/test_cmd_line.py
+file path=usr/lib/python3.5/test/test_cmd_line_script.py
+file path=usr/lib/python3.5/test/test_code.py
+file path=usr/lib/python3.5/test/test_code_module.py
+file path=usr/lib/python3.5/test/test_codeccallbacks.py
+file path=usr/lib/python3.5/test/test_codecencodings_cn.py
+file path=usr/lib/python3.5/test/test_codecencodings_hk.py
+file path=usr/lib/python3.5/test/test_codecencodings_iso2022.py
+file path=usr/lib/python3.5/test/test_codecencodings_jp.py
+file path=usr/lib/python3.5/test/test_codecencodings_kr.py
+file path=usr/lib/python3.5/test/test_codecencodings_tw.py
+file path=usr/lib/python3.5/test/test_codecmaps_cn.py
+file path=usr/lib/python3.5/test/test_codecmaps_hk.py
+file path=usr/lib/python3.5/test/test_codecmaps_jp.py
+file path=usr/lib/python3.5/test/test_codecmaps_kr.py
+file path=usr/lib/python3.5/test/test_codecmaps_tw.py
+file path=usr/lib/python3.5/test/test_codecs.py
+file path=usr/lib/python3.5/test/test_codeop.py
+file path=usr/lib/python3.5/test/test_collections.py
+file path=usr/lib/python3.5/test/test_colorsys.py
+file path=usr/lib/python3.5/test/test_compare.py
+file path=usr/lib/python3.5/test/test_compile.py
+file path=usr/lib/python3.5/test/test_compileall.py
+file path=usr/lib/python3.5/test/test_complex.py
+file path=usr/lib/python3.5/test/test_concurrent_futures.py
+file path=usr/lib/python3.5/test/test_configparser.py
+file path=usr/lib/python3.5/test/test_contains.py
+file path=usr/lib/python3.5/test/test_contextlib.py
+file path=usr/lib/python3.5/test/test_copy.py
+file path=usr/lib/python3.5/test/test_copyreg.py
+file path=usr/lib/python3.5/test/test_coroutines.py
+file path=usr/lib/python3