23245656 Deliver mozjs-24 24.2.0 in Solaris
authorNiveditha Rau <Niveditha.Rau@Oracle.COM>
Fri, 01 Jul 2016 13:03:40 +0000
changeset 6336 6ba7729e5c3a
parent 6335 8129e14951cc
child 6337 04b0a94159cf
23245656 Deliver mozjs-24 24.2.0 in Solaris PSARC/2016/413 GNOME 3 Web Bundle
components/desktop/mozjs-24/Makefile
components/desktop/mozjs-24/mozjs-24.license
components/desktop/mozjs-24/mozjs-24.p5m
components/desktop/mozjs-24/patches/00-psutil-latest.patch
components/desktop/mozjs-24/patches/01-psutil.patch
components/desktop/mozjs-24/patches/02-nspr.patch
components/desktop/mozjs-24/patches/03-readline.patch
components/desktop/mozjs-24/patches/04-madvise.patch
components/desktop/mozjs-24/patches/05-ion_AsmJS_x86.patch
components/desktop/mozjs-24/patches/06-bits.patch
components/desktop/mozjs-24/patches/07-mileston.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/Makefile	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,94 @@
+#
+# 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) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+BUILD_BITS =            32_and_64
+COMPILER =              gcc
+include ../../../make-rules/shared-macros.mk
+
+COMPONENT_NAME=		mozjs
+COMPONENT_VERSION=	24.2.0
+COMPONENT_PROJECT_URL=	https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey
+COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.bz2
+COMPONENT_ARCHIVE_HASH= \
+	sha256:e62f3f331ddd90df1e238c09d61a505c516fe9fd8c5c95336611d191d18437d8
+COMPONENT_ARCHIVE_URL=	http://ftp.mozilla.org/pub/mozilla.org/js/$(COMPONENT_ARCHIVE)
+COMPONENT_BUGDB=	library/libmozjs
+
+TPNO=			25517
+
+CXXFLAGS += -std=c++11
+
+# Only used during build process.
+PYTHON_VERSIONS= 2.7
+PYTHON= $(PYTHON.2.7.$(BITS))
+
+# Tests take too long to run, disabled for now
+TEST_TARGET = $(SKIP_TEST)
+
+include $(WS_MAKE_RULES)/common.mk
+
+# configure script is not at root of source tree.
+CONFIGURE_SCRIPT= $(SOURCE_DIR)/js/src/configure
+
+CONFIGURE_ENV += LDSHARED="$(CC) -shared"
+CONFIGURE_ENV += NSPR_CONFIG="/usr/bin/pkg-config nspr"
+
+# So build can find dtrace.
+COMPONENT_BUILD_ENV += PATH="$(PATH):/usr/sbin"
+
+CONFIGURE_OPTIONS += --enable-ctypes
+CONFIGURE_OPTIONS += --enable-dtrace
+# Uses ancient embedded version of ICU.
+CONFIGURE_OPTIONS += --disable-intl-api
+# Resulting packages are a few hundred megabytes larger without this!
+CONFIGURE_OPTIONS += --enable-install-strip
+CONFIGURE_OPTIONS += --enable-readline
+CONFIGURE_OPTIONS += --enable-shared-js
+CONFIGURE_OPTIONS += --enable-system-ffi
+CONFIGURE_OPTIONS += --enable-threadsafe
+CONFIGURE_OPTIONS += --with-system-zlib
+CONFIGURE_OPTIONS += --with-x
+CONFIGURE_OPTIONS.32 += --with-system-nspr
+# A pkg-config file isn't shipped in Solaris for nspr 64-bit, so configure will
+# fail to find it, requiring manual specification of the flags and libs.
+CONFIGURE_OPTIONS.64 += --with-nspr-cflags="-I/usr/include/mps"
+CONFIGURE_OPTIONS.64 += --with-nspr-libs="-R/usr/lib/mps/64 -L/usr/lib/mps/64 -lplds4 -lplc4 -lnspr4"
+
+unexport SHELLOPTS
+COMPONENT_TEST_ARGS =   -k -i
+COMPONENT_TEST_TRANSFORMS += \
+        '-n ' \
+        '-e "/TOTAL:/p" ' \
+        '-e "/SKIP:/p" ' \
+        '-e "/PASS:/p" ' \
+        '-e "/FAIL:/p" ' \
+        '-e "/ERROR:/p" '
+
+REQUIRED_PACKAGES += library/libffi
+REQUIRED_PACKAGES += library/nspr
+REQUIRED_PACKAGES += library/readline
+REQUIRED_PACKAGES += library/security/nss
+REQUIRED_PACKAGES += library/zlib
+REQUIRED_PACKAGES += system/library/gcc/gcc-c++-runtime
+REQUIRED_PACKAGES += system/library/gcc/gcc-c-runtime
+REQUIRED_PACKAGES += system/library/math
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/mozjs-24.license	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,1148 @@
+
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
+
+-----------------------------------------------------------------------------------
+
+mozjs-24.2.0/mfbt/MSStdInt.h
+
+ Copyright (c) 2006-2008 Alexander Chemeris 
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+ 
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+ 
+   3. The name of the author may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------------------
+
+ mozjs-24.2.0/js/src/testing/mozbase/mozdevice/mozdevice/Zeroconf.py
+
+    Copyright (C) 2003, Paul Scott-Murphy
+
+    This module provides a framework for the use of DNS Service Discovery
+    using IP multicast.  It has been tested against the JRendezvous
+    implementation from <a href="http://strangeberry.com">StrangeBerry</a>,
+    and against the mDNSResponder from Mac OS X 10.3.8.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+    
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+-----------------------------------------------------------------------------------
+
+mozjs-24.2.0/js/src/dtoa.c
+
+ Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose without fee is hereby granted, provided that this entire notice
+ is included in all copies of any software which is or includes a copy
+ or modification of this software and in all copies of the supporting
+ documentation for such software.
+
+ THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+
+----------------------------------------------------------------------------------- 
+
+mozjs-24.2.0/js/src/editline 
+
+ Copyright 1992,1993 Simmule Turner and Rich Salz.  All rights reserved.
+
+ This software is not subject to any license of the American Telephone
+ and Telegraph Company or of the Regents of the University of California.
+
+ Permission is granted to anyone to use this software for any purpose on
+ any computer system, and to alter it and redistribute it freely, subject
+ to the following restrictions:
+ 1. The authors are not responsible for the consequences of use of this
+    software, no matter how awful, even if they arise from flaws in it.
+ 2. The origin of this software must not be misrepresented, either by
+    explicit claim or by omission.  Since few users ever read sources,
+    credits must appear in the documentation.
+ 3. Altered versions must be plainly marked as such, and must not be
+    misrepresented as being the original software.  Since few users
+    ever read sources, credits must appear in the documentation.
+ 4. This notice may not be removed or altered.
+ 
+-----------------------------------------------------------------------------------
+
+mozjs-24.2.0/js/src/ctypes/libffi/src/ 
+
+   Copyright (c) 1996, 1998, 2007  Red Hat, Inc.
+
+   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.
+
+-----------------------------------------------------------------------------------
+
+mozjs-24.2.0/mfbt/double-conversion  
+
+ Copyright 2006-2008 the V8 project authors. All rights reserved.
+ Copyright 2012 the V8 project authors. All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+     * Neither the name of Google Inc. nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------------------
+ 
+mozjs-24.2.0/js/src/python/which/launcher.cpp
+
+ Copyright (c) 2002-2003 ActiveState Corp.
+ Author: Trent Mick ([email protected])
+ 
+ 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.
+ 
+-----------------------------------------------------------------------------------
+ 
+mozjs-24.2.0/js/src/python/psutil/psutil           
+ 
+ Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+
+-----------------------------------------------------------------------------------
+ 
+mozjs-24.2.0/js/src/ctypes/libffi/src/mips
+mozjs-24.2.0/js/src/ctypes/libffi/src/m32r
+mozjs-24.2.0/js/src/ctypes/libffi/src/sparc
+mozjs-24.2.0/js/src/ctypes/libffi/src/cris
+mozjs-24.2.0/js/src/ctypes/libffi/src/x86    
+
+           Copyright (c) 1996-2010  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
+           Copyright (C) 2008  Free Software Foundation, Inc.
+           Copyright (c) 2008  David Daney
+           Copyright (c) 2004  Renesas Technology
+           Copyright (c) 1998  Cygnus Solutions
+           Copyright (c) 2004  Simon Posnjak
+	   Copyright (c) 2005  Axis Communications AB
+           Copyright (c) 2008  Björn König
+
+           Copyright (c) 2001  John Beniton
+           Copyright (c) 2009  Daniel Witte
+
+
+   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.
+
+
+-----------------------------------------------------------------------------------
+
+mozjs-24/mozjs-24.2.0/js/src/yarr 
+
+Copyright (C) 2007-2012 Apple Inc. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1.  Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer. 
+ 2.  Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution. 
+ 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission. 
+ 
+ THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Copyright (C) 2009 Apple Inc. All rights reserved.
+ Copyright (C) 2010 Peter Varga ([email protected]), University of Szeged
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1.  Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer. 
+ 2.  Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution. 
+ 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission. 
+
+ THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR 
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/mozjs-24.p5m	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,124 @@
+#
+# 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) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+<transform file path=usr.*/man/.+ -> \
+    default mangler.man.stability "pass-through volatile">
+set name=pkg.fmri \
+    value=pkg:/library/libmozjs-24@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary value="Mozilla's SpiderMonkey engine JavaScript library"
+set name=pkg.description \
+    value="SpiderMonkey is Mozilla's JavaScript engine written in C/C++. It is used in various Mozilla products, including Firefox"
+set name=pkg.linted.userland.action001.3 value=true
+set name=com.oracle.info.description value=$(COMPONENT_NAME)
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification \
+    value="org.opensolaris.category.2008:Development/Other Languages"
+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/2016/413
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+file path=usr/bin/$(MACH64)/js$(COMPONENT_VERSION)-config
+file usr/bin/$(MACH64)/js$(COMPONENT_VERSION) \
+    path=usr/bin/js$(COMPONENT_VERSION)
+file path=usr/bin/js$(COMPONENT_VERSION)-config
+file path=usr/include/mozjs-24/javascript-trace.h
+file path=usr/include/mozjs-24/js-config.h
+file path=usr/include/mozjs-24/js.msg
+file path=usr/include/mozjs-24/js/Anchor.h
+file path=usr/include/mozjs-24/js/CallArgs.h
+file path=usr/include/mozjs-24/js/CharacterEncoding.h
+file path=usr/include/mozjs-24/js/Date.h
+file path=usr/include/mozjs-24/js/GCAPI.h
+file path=usr/include/mozjs-24/js/HashTable.h
+file path=usr/include/mozjs-24/js/HeapAPI.h
+file path=usr/include/mozjs-24/js/LegacyIntTypes.h
+file path=usr/include/mozjs-24/js/MemoryMetrics.h
+file path=usr/include/mozjs-24/js/PropertyKey.h
+file path=usr/include/mozjs-24/js/RequiredDefines.h
+file path=usr/include/mozjs-24/js/RootingAPI.h
+file path=usr/include/mozjs-24/js/TemplateLib.h
+file path=usr/include/mozjs-24/js/Utility.h
+file path=usr/include/mozjs-24/js/Value.h
+file path=usr/include/mozjs-24/js/Vector.h
+file path=usr/include/mozjs-24/jsalloc.h
+file path=usr/include/mozjs-24/jsapi.h
+file path=usr/include/mozjs-24/jsclass.h
+file path=usr/include/mozjs-24/jsclist.h
+file path=usr/include/mozjs-24/jscpucfg.h
+file path=usr/include/mozjs-24/jsdbgapi.h
+file path=usr/include/mozjs-24/jsfriendapi.h
+file path=usr/include/mozjs-24/jslock.h
+file path=usr/include/mozjs-24/jsperf.h
+file path=usr/include/mozjs-24/jsprf.h
+file path=usr/include/mozjs-24/jsprototypes.h
+file path=usr/include/mozjs-24/jsproxy.h
+file path=usr/include/mozjs-24/jsprvtd.h
+file path=usr/include/mozjs-24/jspubtd.h
+file path=usr/include/mozjs-24/jstypes.h
+file path=usr/include/mozjs-24/jsutil.h
+file path=usr/include/mozjs-24/jsversion.h
+file path=usr/include/mozjs-24/jswrapper.h
+file path=usr/include/mozjs-24/mozilla/Assertions.h
+file path=usr/include/mozjs-24/mozilla/Atomics.h
+file path=usr/include/mozjs-24/mozilla/Attributes.h
+file path=usr/include/mozjs-24/mozilla/BloomFilter.h
+file path=usr/include/mozjs-24/mozilla/Casting.h
+file path=usr/include/mozjs-24/mozilla/Char16.h
+file path=usr/include/mozjs-24/mozilla/CheckedInt.h
+file path=usr/include/mozjs-24/mozilla/Compiler.h
+file path=usr/include/mozjs-24/mozilla/Constants.h
+file path=usr/include/mozjs-24/mozilla/DebugOnly.h
+file path=usr/include/mozjs-24/mozilla/Decimal.h
+file path=usr/include/mozjs-24/mozilla/Endian.h
+file path=usr/include/mozjs-24/mozilla/EnumSet.h
+file path=usr/include/mozjs-24/mozilla/FloatingPoint.h
+file path=usr/include/mozjs-24/mozilla/GuardObjects.h
+file path=usr/include/mozjs-24/mozilla/HashFunctions.h
+file path=usr/include/mozjs-24/mozilla/Likely.h
+file path=usr/include/mozjs-24/mozilla/LinkedList.h
+file path=usr/include/mozjs-24/mozilla/MSStdInt.h
+file path=usr/include/mozjs-24/mozilla/MathAlgorithms.h
+file path=usr/include/mozjs-24/mozilla/MemoryChecking.h
+file path=usr/include/mozjs-24/mozilla/NullPtr.h
+file path=usr/include/mozjs-24/mozilla/PodOperations.h
+file path=usr/include/mozjs-24/mozilla/Poison.h
+file path=usr/include/mozjs-24/mozilla/Range.h
+file path=usr/include/mozjs-24/mozilla/RangedPtr.h
+file path=usr/include/mozjs-24/mozilla/RefPtr.h
+file path=usr/include/mozjs-24/mozilla/SHA1.h
+file path=usr/include/mozjs-24/mozilla/Scoped.h
+file path=usr/include/mozjs-24/mozilla/SplayTree.h
+file path=usr/include/mozjs-24/mozilla/StandardInteger.h
+file path=usr/include/mozjs-24/mozilla/ThreadLocal.h
+file path=usr/include/mozjs-24/mozilla/TypeTraits.h
+file path=usr/include/mozjs-24/mozilla/TypedEnum.h
+file path=usr/include/mozjs-24/mozilla/Types.h
+file path=usr/include/mozjs-24/mozilla/Util.h
+file path=usr/include/mozjs-24/mozilla/WeakPtr.h
+file path=usr/lib/$(MACH64)/libmozjs-24.so
+file path=usr/lib/$(MACH64)/pkgconfig/mozjs-24.pc
+file path=usr/lib/libmozjs-24.so
+file path=usr/lib/pkgconfig/mozjs-24.pc
+license mozjs-24.license license="MPLv2, LGPLv2, BSD"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/00-psutil-latest.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,38301 @@
+Updates the embedded version of psutil to one that supports Solaris.
+
+Not appropriate for upstream as newest upstream version already includes these fixes.
+--- mozjs-24.2.0/js/src/python/psutil/.travis.yml	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/.travis.yml	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,25 @@
++language: python
++python:
++    - 2.6
++    - 2.7
++    - 3.2
++    - 3.3
++    - 3.4
++    # - pypy
++install:
++    - if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install -U ipaddress unittest2 mock; fi
++    - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install -U ipaddress mock; fi
++    - if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then pip install -U ipaddress mock; fi
++    - if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install -U ipaddress; fi
++script:
++    - pip install flake8 pep8
++    - python setup.py build
++    - python setup.py install
++    - python test/test_psutil.py
++    - python test/test_memory_leaks.py
++    - flake8
++    - pep8
++os:
++    - linux
++    - osx
++
+--- mozjs-24.2.0/js/src/python/psutil/CREDITS	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/CREDITS	2015-06-17 19:33:33.000000000 -0700
+@@ -1,36 +1,37 @@
+-
+ Intro
+ =====
+ 
+-We would like to recognize some of the people who have been instrumental in the
++I would like to recognize some of the people who have been instrumental in the
+ development of psutil.
+-I'm sure we are forgetting some people (feel free to email us), but here is a
++I'm sure I'm forgetting some people (feel free to email me), but here is a
+ short list.
+ It's modeled after the Linux CREDITS file where the fields are:
+ name (N), e-mail (E), web-address (W), country (C), description (D), (I) issues
+-(issue tracker is at http://code.google.com/p/psutil/issues/list).
++(issue tracker is at https://github.com/giampaolo/psutil/issues).
+ Really thanks to all of you.
+ 
++- Giampaolo
+ 
+-Maintainers
+-===========
++Author
++======
+ 
+ N: Giampaolo Rodola'
+ C: Italy
+ E: [email protected]
+-W: http://www.linkedin.com/in/grodola
++W: http://grodola.blogspot.com/
++
++Contributors
++============
+ 
+ N: Jay Loden
+ C: NJ, USA
+ E: [email protected]
++D: original co-author, initial design/bootstrap and occasional bug fixes
+ W: http://www.jayloden.com
+ 
+-
+-Contributors
+-============
+-
+ N: Jeremy Whitlock
+ E: [email protected]
++D: great help with OSX C development.
+ I: 125, 150, 174, 206
+ 
+ N: wj32
+@@ -41,12 +42,19 @@
+ N: Yan Raber
+ C: Bologna, Italy
+ E: [email protected]
+-D: help on Windows development
++D: help on Windows development (initial version of Process.username())
++
++N: Justin Venus
++E: [email protected]
++D: Solaris support
++I: 18
+ 
+ N: Dave Daeschler
+ C: USA
+ E: [email protected]
+-D: initial design/bootstrap and continuing bug fixes
++W: http://daviddaeschler.com
++D: some contributions to initial design/bootstrap plus occasional bug fixing
++I: 522, 536
+ 
+ N: cjgohlke
+ E: [email protected]
+@@ -162,3 +170,141 @@
+ N: Jan Beich
+ E: [email protected]
+ I: 325
++
++N: floppymaster
++E: [email protected]
++I: 380
++
++N: Arfrever.FTA
++E: [email protected]
++I: 369, 404
++
++N: danudey
++E: [email protected]
++I: 386
++
++N: Adrien Fallou
++I: 224
++
++N: Gisle Vanem
++E: [email protected]
++I: 411
++
++N: thepyr0
++E: [email protected]
++I: 414
++
++N: John Pankov
++E: [email protected]
++I: 435
++
++N: Matt Good
++W: http://matt-good.net/
++I: 438
++
++N: Ulrich Klank
++E: [email protected]
++I: 448
++
++N: Josiah Carlson
++E: [email protected]
++I: 451, 452
++
++N: Raymond Hettinger
++D: namedtuple and lru_cache backward compatible implementations.
++
++N: Jason Kirtland
++D: backward compatible implementation of collections.defaultdict.
++
++M: Ken Seeho
++D: @cached_property decorator
++
++N: crusaderky
++E: [email protected]
++I: 470, 477
++
++E: [email protected]
++I: 471
++
++N: Gautam Singh
++E: [email protected]
++I: 466
++
++E: [email protected]
++I: 476, 479
++
++N: Francois Charron
++E: [email protected]
++I: 474
++
++N: Naveed Roudsari
++E: [email protected]
++I: 421
++
++N: Alexander Grothe
++E: [email protected]
++I: 497
++
++N: Szigeti Gabor Niif
++E: [email protected]
++I: 446
++
++N: msabramo
++E: [email protected]
++I: 492
++
++N: Jeff Tang
++W: https://github.com/mrjefftang
++I: 340, 529, 616
++
++N: Yaolong Huang
++E: [email protected]
++W: http://airekans.github.io/
++I: 530
++
++N: Anders Chrigström
++W: https://github.com/anders-chrigstrom
++I: 496
++
++N: spacewander
++E: [email protected]
++I: 561
++
++N: Sylvain Mouquet
++E: [email protected]
++I: 565
++
++N: karthikrev
++I: 568
++
++N: Bruno Binet
++E: [email protected]
++I: 572
++
++N: Gabi Davar
++C: Israel
++W: https://github.com/mindw
++I: 578, 581, 587
++
++N: spacewanderlzx
++C: Guangzhou,China
++E: [email protected]
++I: 555
++
++N: Fabian Groffen
++I: 611, 618
++
++N: desbma
++W: https://github.com/desbma
++C: France
++I: 628
++
++N: John Burnett
++W: http://www.johnburnett.com/
++C: Irvine, CA, US
++I: 614
++
++N: Árni Már Jónsson
++E: Reykjavik, Iceland
++E: https://github.com/arnimarj
++I: 634
+--- mozjs-24.2.0/js/src/python/psutil/docs/_static/copybutton.js	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_static/copybutton.js	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,57 @@
++$(document).ready(function() {
++    /* Add a [>>>] button on the top-right corner of code samples to hide
++     * the >>> and ... prompts and the output and thus make the code
++     * copyable. */
++    var div = $('.highlight-python .highlight,' +
++                '.highlight-python3 .highlight')
++    var pre = div.find('pre');
++
++    // get the styles from the current theme
++    pre.parent().parent().css('position', 'relative');
++    var hide_text = 'Hide the prompts and output';
++    var show_text = 'Show the prompts and output';
++    var border_width = pre.css('border-top-width');
++    var border_style = pre.css('border-top-style');
++    var border_color = pre.css('border-top-color');
++    var button_styles = {
++        'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
++        'border-color': border_color, 'border-style': border_style,
++        'border-width': border_width, 'color': border_color, 'text-size': '75%',
++        'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
++        'border-radius': '0 3px 0 0'
++    }
++
++    // create and add the button to all the code blocks that contain >>>
++    div.each(function(index) {
++        var jthis = $(this);
++        if (jthis.find('.gp').length > 0) {
++            var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
++            button.css(button_styles)
++            button.attr('title', hide_text);
++            jthis.prepend(button);
++        }
++        // tracebacks (.gt) contain bare text elements that need to be
++        // wrapped in a span to work with .nextUntil() (see later)
++        jthis.find('pre:has(.gt)').contents().filter(function() {
++            return ((this.nodeType == 3) && (this.data.trim().length > 0));
++        }).wrap('<span>');
++    });
++
++    // define the behavior of the button when it's clicked
++    $('.copybutton').toggle(
++        function() {
++            var button = $(this);
++            button.parent().find('.go, .gp, .gt').hide();
++            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
++            button.css('text-decoration', 'line-through');
++            button.attr('title', show_text);
++        },
++        function() {
++            var button = $(this);
++            button.parent().find('.go, .gp, .gt').show();
++            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
++            button.css('text-decoration', 'none');
++            button.attr('title', hide_text);
++        });
++});
++
+--- mozjs-24.2.0/js/src/python/psutil/docs/_static/sidebar.js	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_static/sidebar.js	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,161 @@
++/*
++ * sidebar.js
++ * ~~~~~~~~~~
++ *
++ * This script makes the Sphinx sidebar collapsible.
++ *
++ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds in
++ * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
++ * collapse and expand the sidebar.
++ *
++ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the
++ * width of the sidebar and the margin-left of the document are decreased.
++ * When the sidebar is expanded the opposite happens.  This script saves a
++ * per-browser/per-session cookie used to remember the position of the sidebar
++ * among the pages.  Once the browser is closed the cookie is deleted and the
++ * position reset to the default (expanded).
++ *
++ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
++ * :license: BSD, see LICENSE for details.
++ *
++ */
++
++$(function() {
++  // global elements used by the functions.
++  // the 'sidebarbutton' element is defined as global after its
++  // creation, in the add_sidebar_button function
++  var bodywrapper = $('.bodywrapper');
++  var sidebar = $('.sphinxsidebar');
++  var sidebarwrapper = $('.sphinxsidebarwrapper');
++
++  // original margin-left of the bodywrapper and width of the sidebar
++  // with the sidebar expanded
++  var bw_margin_expanded = bodywrapper.css('margin-left');
++  var ssb_width_expanded = sidebar.width();
++
++  // margin-left of the bodywrapper and width of the sidebar
++  // with the sidebar collapsed
++  var bw_margin_collapsed = '.8em';
++  var ssb_width_collapsed = '.8em';
++
++  // colors used by the current theme
++  var dark_color = '#AAAAAA';
++  var light_color = '#CCCCCC';
++
++  function sidebar_is_collapsed() {
++    return sidebarwrapper.is(':not(:visible)');
++  }
++
++  function toggle_sidebar() {
++    if (sidebar_is_collapsed())
++      expand_sidebar();
++    else
++      collapse_sidebar();
++  }
++
++  function collapse_sidebar() {
++    sidebarwrapper.hide();
++    sidebar.css('width', ssb_width_collapsed);
++    bodywrapper.css('margin-left', bw_margin_collapsed);
++    sidebarbutton.css({
++        'margin-left': '0',
++        //'height': bodywrapper.height(),
++        'height': sidebar.height(),
++        'border-radius': '5px'
++    });
++    sidebarbutton.find('span').text('»');
++    sidebarbutton.attr('title', _('Expand sidebar'));
++    document.cookie = 'sidebar=collapsed';
++  }
++
++  function expand_sidebar() {
++    bodywrapper.css('margin-left', bw_margin_expanded);
++    sidebar.css('width', ssb_width_expanded);
++    sidebarwrapper.show();
++    sidebarbutton.css({
++        'margin-left': ssb_width_expanded-12,
++        //'height': bodywrapper.height(),
++        'height': sidebar.height(),
++        'border-radius': '0 5px 5px 0'
++    });
++    sidebarbutton.find('span').text('«');
++    sidebarbutton.attr('title', _('Collapse sidebar'));
++    //sidebarwrapper.css({'padding-top':
++    //  Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)});
++    document.cookie = 'sidebar=expanded';
++  }
++
++  function add_sidebar_button() {
++    sidebarwrapper.css({
++        'float': 'left',
++        'margin-right': '0',
++        'width': ssb_width_expanded - 28
++    });
++    // create the button
++    sidebar.append(
++      '<div id="sidebarbutton"><span>&laquo;</span></div>'
++    );
++    var sidebarbutton = $('#sidebarbutton');
++    // find the height of the viewport to center the '<<' in the page
++    var viewport_height;
++    if (window.innerHeight)
++ 	  viewport_height = window.innerHeight;
++    else
++	  viewport_height = $(window).height();
++    var sidebar_offset = sidebar.offset().top;
++
++    var sidebar_height = sidebar.height();
++    //var sidebar_height = Math.max(bodywrapper.height(), sidebar.height());
++    sidebarbutton.find('span').css({
++        'display': 'block',
++        'margin-top': sidebar_height/2 - 10
++        //'margin-top': (viewport_height - sidebar.position().top - 20) / 2
++        //'position': 'fixed',
++        //'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10
++    });
++
++    sidebarbutton.click(toggle_sidebar);
++    sidebarbutton.attr('title', _('Collapse sidebar'));
++    sidebarbutton.css({
++        'border-radius': '0 5px 5px 0',
++        'color': '#444444',
++        'background-color': '#CCCCCC',
++        'font-size': '1.2em',
++        'cursor': 'pointer',
++        'height': sidebar_height,
++        'padding-top': '1px',
++        'padding-left': '1px',
++        'margin-left': ssb_width_expanded - 12
++    });
++
++    sidebarbutton.hover(
++      function () {
++          $(this).css('background-color', dark_color);
++      },
++      function () {
++          $(this).css('background-color', light_color);
++      }
++    );
++  }
++
++  function set_position_from_cookie() {
++    if (!document.cookie)
++      return;
++    var items = document.cookie.split(';');
++    for(var k=0; k<items.length; k++) {
++      var key_val = items[k].split('=');
++      var key = key_val[0];
++      if (key == 'sidebar') {
++        var value = key_val[1];
++        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
++          collapse_sidebar();
++        else if ((value == 'expanded') && (sidebar_is_collapsed()))
++          expand_sidebar();
++      }
++    }
++  }
++
++  add_sidebar_button();
++  var sidebarbutton = $('#sidebarbutton');
++  set_position_from_cookie();
++});
+--- mozjs-24.2.0/js/src/python/psutil/docs/_template/globaltoc.html	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_template/globaltoc.html	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,12 @@
++{#
++    basic/globaltoc.html
++    ~~~~~~~~~~~~~~~~~~~~
++
++    Sphinx sidebar template: global table of contents.
++
++    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
++    :license: BSD, see LICENSE for details.
++#}
++<h3>{{ _('Manual') }}</h3>
++{{ toctree() }}
++<a href="{{ pathto(master_doc) }}">Back to Welcome</a>
+--- mozjs-24.2.0/js/src/python/psutil/docs/_template/indexcontent.html	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_template/indexcontent.html	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,4 @@
++{% extends "defindex.html" %}
++{% block tables %}
++
++{% endblock %}
+--- mozjs-24.2.0/js/src/python/psutil/docs/_template/indexsidebar.html	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_template/indexsidebar.html	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,8 @@
++<h3>Useful links</h3>
++<ul>
++  <li><a href="https://github.com/giampaolo/psutil">Github project</a></li>
++  <li><a href="http://grodola.blogspot.com/search/label/psutil">Blog</a></li>
++  <li><a href="https://pypi.python.org/pypi?:action=display&name=psutil#downloads">Download</a></li>
++  <li><a href="https://github.com/giampaolo/psutil/issues">Issues</a></li>
++  <li><a href="http://groups.google.com/group/psutil/topics">Forum</a></li>
++</ul>
+--- mozjs-24.2.0/js/src/python/psutil/docs/_template/page.html	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_template/page.html	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,66 @@
++{% extends "!page.html" %}
++{% block extrahead %}
++{{ super() }}
++{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
++<script type="text/javascript">
++
++  // Store editor pop-up help state in localStorage
++  // so it does not re-pop-up itself between page loads.
++  // Do not even to pretend to support IE gracefully.
++  (function($) {
++
++    $(document).ready(function() {
++        var box = $("#editor-trap");
++        var klass = "toggled";
++        var storageKey = "toggled";
++
++        function toggle() {
++            box.toggleClass(klass);
++            // Store the toggle status in local storage as "has value string" or null
++            window.localStorage.setItem(storageKey, box.hasClass(klass) ? "toggled" : "not-toggled");
++        }
++
++        box.click(toggle);
++
++        // Check the persistent state of the editor pop-up
++        // Note that localStorage does not necessarily support boolean values (ugh!)
++        // http://stackoverflow.com/questions/3263161/cannot-set-boolean-values-in-localstorage
++        var v = window.localStorage.getItem(storageKey);
++        if(v == "toggled" || !v) {
++          box.addClass(klass);
++        }
++
++    });
++
++  })(jQuery);
++</script>
++<script type="text/javascript">
++
++  var _gaq = _gaq || [];
++  _gaq.push(['_setAccount', 'UA-2097050-4']);
++  _gaq.push(['_trackPageview']);
++
++  (function() {
++    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
++    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
++    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
++  })();
++
++</script>
++{% endblock %}
++
++{% block rootrellink %}
++    <li><a href="https://github.com/giampaolo/psutil/"><img src="{{ pathto('_static/logo.png', 1) }}" style="height: 30px; vertical-align: middle; padding-right: 1em;" /> Project Homepage</a>{{ reldelim1 }}</li>
++	<li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
++{% endblock %}
++
++
++{% block footer %}
++<div class="footer">
++    &copy; Copyright {{ copyright|e }}.
++    <br />
++    Last updated on {{ last_updated|e }}.
++    <br />
++    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version|e }}.
++</div>
++{% endblock %}
+\ No newline at end of file
+--- mozjs-24.2.0/js/src/python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_themes/pydoctheme/static/pydoctheme.css	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,187 @@
++@import url("default.css");
++
++body {
++    background-color: white;
++    margin-left: 1em;
++    margin-right: 1em;
++}
++
++div.related {
++    margin-bottom: 1.2em;
++    padding: 0.5em 0;
++    border-top: 1px solid #ccc;
++    margin-top: 0.5em;
++}
++
++div.related a:hover {
++    color: #0095C4;
++}
++
++div.related:first-child {
++    border-top: 0;
++    padding-top: 0;
++    border-bottom: 1px solid #ccc;
++}
++
++div.sphinxsidebar {
++    background-color: #eeeeee;
++    border-radius: 5px;
++    line-height: 130%;
++    font-size: smaller;
++}
++
++div.sphinxsidebar h3, div.sphinxsidebar h4 {
++    margin-top: 1.5em;
++}
++
++div.sphinxsidebarwrapper > h3:first-child {
++    margin-top: 0.2em;
++}
++
++div.sphinxsidebarwrapper > ul > li > ul > li {
++    margin-bottom: 0.4em;
++}
++
++div.sphinxsidebar a:hover {
++    color: #0095C4;
++}
++
++div.sphinxsidebar input {
++    font-family: 'Lucida Grande','Lucida Sans','DejaVu Sans',Arial,sans-serif;
++    border: 1px solid #999999;
++    font-size: smaller;
++    border-radius: 3px;
++}
++
++div.sphinxsidebar input[type=text] {
++    max-width: 150px;
++}
++
++div.body {
++    padding: 0 0 0 1.2em;
++}
++
++div.body p {
++    line-height: 140%;
++}
++
++div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 {
++    margin: 0;
++    border: 0;
++    padding: 0.3em 0;
++}
++
++div.body hr {
++    border: 0;
++    background-color: #ccc;
++    height: 1px;
++}
++
++div.body pre {
++    border-radius: 3px;
++    border: 1px solid #ac9;
++}
++
++div.body div.admonition, div.body div.impl-detail {
++    border-radius: 3px;
++}
++
++div.body div.impl-detail > p {
++    margin: 0;
++}
++
++div.body div.seealso {
++    border: 1px solid #dddd66;
++}
++
++div.body a {
++    color: #00608f;
++}
++
++div.body a:visited {
++    color: #30306f;
++}
++
++div.body a:hover {
++    color: #00B0E4;
++}
++
++tt, pre {
++    font-family: monospace, sans-serif;
++    font-size: 96.5%;
++}
++
++div.body tt {
++    border-radius: 3px;
++}
++
++div.body tt.descname {
++    font-size: 120%;
++}
++
++div.body tt.xref, div.body a tt {
++    font-weight: normal;
++}
++
++p.deprecated {
++    border-radius: 3px;
++}
++
++table.docutils {
++    border: 1px solid #ddd;
++    min-width: 20%;
++    border-radius: 3px;
++    margin-top: 10px;
++    margin-bottom: 10px;
++}
++
++table.docutils td, table.docutils th {
++    border: 1px solid #ddd !important;
++    border-radius: 3px;
++}
++
++table p, table li {
++    text-align: left !important;
++}
++
++table.docutils th {
++    background-color: #eee;
++    padding: 0.3em 0.5em;
++}
++
++table.docutils td {
++    background-color: white;
++    padding: 0.3em 0.5em;
++}
++
++table.footnote, table.footnote td {
++    border: 0 !important;
++}
++
++div.footer {
++    line-height: 150%;
++    margin-top: -2em;
++    text-align: right;
++    width: auto;
++    margin-right: 10px;
++}
++
++div.footer a:hover {
++    color: #0095C4;
++}
++
++div.body h1,
++div.body h2,
++div.body h3 {
++    background-color: #EAEAEA;
++    border-bottom: 1px solid #CCC;
++    padding-top: 2px;
++    padding-bottom: 2px;
++    padding-left: 5px;
++    margin-top: 5px;
++    margin-bottom: 5px;
++}
++
++div.body h2 {
++    padding-left:10px;
++}
+--- mozjs-24.2.0/js/src/python/psutil/docs/_themes/pydoctheme/theme.conf	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/_themes/pydoctheme/theme.conf	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,23 @@
++[theme]
++inherit = default
++stylesheet = pydoctheme.css
++pygments_style = sphinx
++
++[options]
++bodyfont = 'Lucida Grande', 'Lucida Sans', 'DejaVu Sans', Arial, sans-serif
++headfont = 'Lucida Grande', 'Lucida Sans', 'DejaVu Sans', Arial, sans-serif
++footerbgcolor = white
++footertextcolor = #555555
++relbarbgcolor = white
++relbartextcolor = #666666
++relbarlinkcolor = #444444
++sidebarbgcolor = white
++sidebartextcolor = #444444
++sidebarlinkcolor = #444444
++bgcolor = white
++textcolor = #222222
++linkcolor = #0090c0
++visitedlinkcolor = #00608f
++headtextcolor = #1a1a1a
++headbgcolor = white
++headlinkcolor = #aaaaaa
+--- mozjs-24.2.0/js/src/python/psutil/docs/conf.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/conf.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,248 @@
++# -*- coding: utf-8 -*-
++#
++# psutil documentation build configuration file, created by
++# sphinx-quickstart.
++#
++# This file is execfile()d with the current directory set to its
++# containing dir.
++#
++# Note that not all possible configuration values are present in this
++# autogenerated file.
++#
++# All configuration values have a default; values that are commented out
++# serve to show the default.
++
++import datetime
++import os
++
++
++PROJECT_NAME = "psutil"
++AUTHOR = "Giampaolo Rodola'"
++THIS_YEAR = str(datetime.datetime.now().year)
++HERE = os.path.abspath(os.path.dirname(__file__))
++
++
++def get_version():
++    INIT = os.path.abspath(os.path.join(HERE, '../psutil/__init__.py'))
++    with open(INIT, 'r') as f:
++        for line in f:
++            if line.startswith('__version__'):
++                ret = eval(line.strip().split(' = ')[1])
++                assert ret.count('.') == 2, ret
++                for num in ret.split('.'):
++                    assert num.isdigit(), ret
++                return ret
++        else:
++            raise ValueError("couldn't find version string")
++
++VERSION = get_version()
++
++# If your documentation needs a minimal Sphinx version, state it here.
++needs_sphinx = '1.0'
++
++# Add any Sphinx extension module names here, as strings. They can be
++# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
++# ones.
++extensions = ['sphinx.ext.autodoc',
++              'sphinx.ext.coverage',
++              'sphinx.ext.pngmath',
++              'sphinx.ext.viewcode',
++              'sphinx.ext.intersphinx']
++
++# Add any paths that contain templates here, relative to this directory.
++templates_path = ['_template']
++
++# The suffix of source filenames.
++source_suffix = '.rst'
++
++# The encoding of source files.
++# source_encoding = 'utf-8-sig'
++
++# The master toctree document.
++master_doc = 'index'
++
++# General information about the project.
++project = PROJECT_NAME
++copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR)
++
++# The version info for the project you're documenting, acts as replacement for
++# |version| and |release|, also used in various other places throughout the
++# built documents.
++#
++# The short X.Y version.
++version = VERSION
++
++# The language for content autogenerated by Sphinx. Refer to documentation
++# for a list of supported languages.
++# language = None
++
++# There are two options for replacing |today|: either, you set today to some
++# non-false value, then it is used:
++# today = ''
++# Else, today_fmt is used as the format for a strftime call.
++# today_fmt = '%B %d, %Y'
++
++# List of patterns, relative to source directory, that match files and
++# directories to ignore when looking for source files.
++exclude_patterns = ['_build']
++
++# The reST default role (used for this markup: `text`) to use for all
++# documents.
++# default_role = None
++
++# If true, '()' will be appended to :func: etc. cross-reference text.
++add_function_parentheses = True
++# If true, the current module name will be prepended to all description
++# unit titles (such as .. function::).
++# add_module_names = True
++
++autodoc_docstring_signature = True
++
++# If true, sectionauthor and moduleauthor directives will be shown in the
++# output. They are ignored by default.
++# show_authors = False
++
++# The name of the Pygments (syntax highlighting) style to use.
++pygments_style = 'sphinx'
++
++# A list of ignored prefixes for module index sorting.
++# modindex_common_prefix = []
++
++
++# -- Options for HTML output -------------------------------------------------
++
++# The theme to use for HTML and HTML Help pages.  See the documentation for
++# a list of builtin themes.
++
++# Theme options are theme-specific and customize the look and feel of a theme
++# further.  For a list of options available for each theme, see the
++# documentation.
++html_theme = 'pydoctheme'
++html_theme_options = {'collapsiblesidebar': True}
++
++# Add any paths that contain custom themes here, relative to this directory.
++html_theme_path = ["_themes"]
++
++# The name for this set of Sphinx documents.  If None, it defaults to
++# "<project> v<release> documentation".
++html_title = "{project} {version} documentation".format(**locals())
++
++# A shorter title for the navigation bar.  Default is the same as html_title.
++# html_short_title = None
++
++# The name of an image file (relative to this directory) to place at the top
++# of the sidebar.
++# html_logo = 'logo.png'
++
++# The name of an image file (within the static path) to use as favicon of the
++# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
++# pixels large.
++html_favicon = '_static/favicon.ico'
++
++# Add any paths that contain custom static files (such as style sheets) here,
++# relative to this directory. They are copied after the builtin static files,
++# so a file named "default.css" will overwrite the builtin "default.css".
++html_static_path = ['_static']
++
++# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
++# using the given strftime format.
++html_last_updated_fmt = '%b %d, %Y'
++
++# If true, SmartyPants will be used to convert quotes and dashes to
++# typographically correct entities.
++html_use_smartypants = True
++
++# Custom sidebar templates, maps document names to template names.
++html_sidebars = {
++    'index': 'indexsidebar.html',
++    '**': ['globaltoc.html',
++           'relations.html',
++           'sourcelink.html',
++           'searchbox.html']
++}
++
++# Additional templates that should be rendered to pages, maps page names to
++# template names.
++# html_additional_pages = {
++#    'index': 'indexcontent.html',
++# }
++
++# If false, no module index is generated.
++html_domain_indices = False
++
++# If false, no index is generated.
++html_use_index = True
++
++# If true, the index is split into individual pages for each letter.
++# html_split_index = False
++
++# If true, links to the reST sources are added to the pages.
++# html_show_sourcelink = True
++
++# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
++# html_show_sphinx = True
++
++# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
++# html_show_copyright = True
++
++# If true, an OpenSearch description file will be output, and all pages will
++# contain a <link> tag referring to it.  The value of this option must be the
++# base URL from which the finished HTML is served.
++# html_use_opensearch = ''
++
++# This is the file name suffix for HTML files (e.g. ".xhtml").
++# html_file_suffix = None
++
++# Output file base name for HTML help builder.
++htmlhelp_basename = '%s-doc' % PROJECT_NAME
++
++# -- Options for LaTeX output ------------------------------------------------
++
++# The paper size ('letter' or 'a4').
++# latex_paper_size = 'letter'
++
++# The font size ('10pt', '11pt' or '12pt').
++# latex_font_size = '10pt'
++
++# Grouping the document tree into LaTeX files. List of tuples
++# (source start file, target name, title, author, documentclass
++# [howto/manual]).
++latex_documents = [
++    ('index', '%s.tex' % PROJECT_NAME,
++     '%s documentation' % PROJECT_NAME, AUTHOR),
++]
++
++# The name of an image file (relative to this directory) to place at
++# the top of the title page.
++# latex_logo = None
++
++# For "manual" documents, if this is true, then toplevel headings are parts,
++# not chapters.
++# latex_use_parts = False
++
++# If true, show page references after internal links.
++# latex_show_pagerefs = False
++
++# If true, show URL addresses after external links.
++# latex_show_urls = False
++
++# Additional stuff for the LaTeX preamble.
++# latex_preamble = ''
++
++# Documents to append as an appendix to all manuals.
++# latex_appendices = []
++
++# If false, no module index is generated.
++# latex_domain_indices = True
++
++
++# -- Options for manual page output ------------------------------------------
++
++# One entry per manual page. List of tuples
++# (source start file, name, description, authors, manual section).
++man_pages = [
++    ('index', PROJECT_NAME, '%s documentation' % PROJECT_NAME, [AUTHOR], 1)
++]
++
++# If true, show URL addresses after external links.
++# man_show_urls = False
+--- mozjs-24.2.0/js/src/python/psutil/docs/index.rst	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/index.rst	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,1377 @@
++.. module:: psutil
++   :synopsis: psutil module
++.. moduleauthor:: Giampaolo Rodola' <[email protected]>
++
++.. warning::
++
++   This documentation refers to new 2.X version of psutil.
++   Instructions on how to port existing 1.2.1 code are
++   `here <http://grodola.blogspot.com/2014/01/psutil-20-porting.html>`__.
++   Old 1.2.1 documentation is still available
++   `here <https://code.google.com/p/psutil/wiki/Documentation>`__.
++
++psutil documentation
++====================
++
++Quick links
++-----------
++
++* `Home page <https://github.com/giampaolo/psutil>`__
++* `Blog <http://grodola.blogspot.com/search/label/psutil>`__
++* `Forum <http://groups.google.com/group/psutil/topics>`__
++* `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`__
++* `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
++* `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`__
++
++About
++-----
++
++From project's home page:
++
++  psutil (python system and process utilities) is a cross-platform library for
++  retrieving information on running
++  **processes** and **system utilization** (CPU, memory, disks, network) in
++  **Python**.
++  It is useful mainly for **system monitoring**, **profiling** and **limiting
++  process resources** and **management of running processes**.
++  It implements many functionalities offered by command line tools
++  such as: *ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice,
++  ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap*.
++  It currently supports **Linux, Windows, OSX, FreeBSD** and **Sun Solaris**,
++  both **32-bit** and **64-bit** architectures, with Python versions from
++  **2.6 to 3.4** (users of Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
++  `PyPy <http://pypy.org/>`__ is also known to work.
++
++The psutil documentation you're reading is distributed as a single HTML page.
++
++System related functions
++========================
++
++CPU
++---
++
++.. function:: cpu_times(percpu=False)
++
++  Return system CPU times as a namedtuple.
++  Every attribute represents the seconds the CPU has spent in the given mode.
++  The attributes availability varies depending on the platform:
++
++  - **user**
++  - **system**
++  - **idle**
++  - **nice** *(UNIX)*
++  - **iowait** *(Linux)*
++  - **irq** *(Linux, FreeBSD)*
++  - **softirq** *(Linux)*
++  - **steal** *(Linux 2.6.11+)*
++  - **guest** *(Linux 2.6.24+)*
++  - **guest_nice** *(Linux 3.2.0+)*
++
++  When *percpu* is ``True`` return a list of namedtuples for each logical CPU
++  on the system.
++  First element of the list refers to first CPU, second element to second CPU
++  and so on.
++  The order of the list is consistent across calls.
++  Example output on Linux:
++
++    >>> import psutil
++    >>> psutil.cpu_times()
++    scputimes(user=17411.7, nice=77.99, system=3797.02, idle=51266.57, iowait=732.58, irq=0.01, softirq=142.43, steal=0.0, guest=0.0, guest_nice=0.0)
++
++.. function:: cpu_percent(interval=None, percpu=False)
++
++  Return a float representing the current system-wide CPU utilization as a
++  percentage. When *interval* is > ``0.0`` compares system CPU times elapsed
++  before and after the interval (blocking).
++  When *interval* is ``0.0`` or ``None`` compares system CPU times elapsed
++  since last call or module import, returning immediately.
++  That means the first time this is called it will return a meaningless ``0.0``
++  value which you are supposed to ignore.
++  In this case is recommended for accuracy that this function be called with at
++  least ``0.1`` seconds between calls.
++  When *percpu* is ``True`` returns a list of floats representing the
++  utilization as a percentage for each CPU.
++  First element of the list refers to first CPU, second element to second CPU
++  and so on. The order of the list is consistent across calls.
++
++    >>> import psutil
++    >>> # blocking
++    >>> psutil.cpu_percent(interval=1)
++    2.0
++    >>> # non-blocking (percentage since last call)
++    >>> psutil.cpu_percent(interval=None)
++    2.9
++    >>> # blocking, per-cpu
++    >>> psutil.cpu_percent(interval=1, percpu=True)
++    [2.0, 1.0]
++    >>>
++
++  .. warning::
++
++    the first time this function is called with *interval* = ``0.0`` or ``None``
++    it will return a meaningless ``0.0`` value which you are supposed to
++    ignore.
++
++.. function:: cpu_times_percent(interval=None, percpu=False)
++
++  Same as :func:`cpu_percent()` but provides utilization percentages for each
++  specific CPU time as is returned by
++  :func:`psutil.cpu_times(percpu=True)<cpu_times()>`.
++  *interval* and
++  *percpu* arguments have the same meaning as in :func:`cpu_percent()`.
++
++  .. warning::
++
++    the first time this function is called with *interval* = ``0.0`` or
++    ``None`` it will return a meaningless ``0.0`` value which you are supposed
++    to ignore.
++
++.. function:: cpu_count(logical=True)
++
++    Return the number of logical CPUs in the system (same as
++    `os.cpu_count() <http://docs.python.org/3/library/os.html#os.cpu_count>`__
++    in Python 3.4).
++    If *logical* is ``False`` return the number of physical cores only (hyper
++    thread CPUs are excluded). Return ``None`` if undetermined.
++
++      >>> import psutil
++      >>> psutil.cpu_count()
++      4
++      >>> psutil.cpu_count(logical=False)
++      2
++      >>>
++
++Memory
++------
++
++.. function:: virtual_memory()
++
++  Return statistics about system memory usage as a namedtuple including the
++  following fields, expressed in bytes:
++
++  - **total**: total physical memory available.
++  - **available**: the actual amount of available memory that can be given
++    instantly to processes that request more memory in bytes; this is
++    calculated by summing different memory values depending on the platform
++    (e.g. free + buffers + cached on Linux) and it is supposed to be used to
++    monitor actual memory usage in a cross platform fashion.
++  - **percent**: the percentage usage calculated as
++    ``(total - available) / total * 100``.
++  - **used**: memory used, calculated differently depending on the platform and
++    designed for informational purposes only.
++  - **free**: memory not being used at all (zeroed) that is readily available;
++    note that this doesn't reflect the actual memory available (use 'available'
++    instead).
++
++  Platform-specific fields:
++
++  - **active**: (UNIX): memory currently in use or very recently used, and so
++    it is in RAM.
++  - **inactive**: (UNIX): memory that is marked as not used.
++  - **buffers**: (Linux, BSD): cache for things like file system metadata.
++  - **cached**: (Linux, BSD): cache for various things.
++  - **wired**: (BSD, OSX): memory that is marked to always stay in RAM. It is
++    never moved to disk.
++  - **shared**: (BSD): memory that may be simultaneously accessed by multiple
++    processes.
++
++  The sum of **used** and **available** does not necessarily equal **total**.
++  On Windows **available** and **free** are the same.
++  See `examples/meminfo.py <https://github.com/giampaolo/psutil/blob/master/examples/meminfo.py>`__
++  script providing an example on how to convert bytes in a human readable form.
++
++    >>> import psutil
++    >>> mem = psutil.virtual_memory()
++    >>> mem
++    svmem(total=8374149120L, available=1247768576L, percent=85.1, used=8246628352L, free=127520768L, active=3208777728, inactive=1133408256, buffers=342413312L, cached=777834496)
++    >>>
++    >>> THRESHOLD = 100 * 1024 * 1024  # 100MB
++    >>> if mem.available <= THRESHOLD:
++    ...     print("warning")
++    ...
++    >>>
++
++
++.. function:: swap_memory()
++
++  Return system swap memory statistics as a namedtuple including the following
++  fields:
++
++  * **total**: total swap memory in bytes
++  * **used**: used swap memory in bytes
++  * **free**: free swap memory in bytes
++  * **percent**: the percentage usage calculated as ``(total - available) / total * 100``
++  * **sin**: the number of bytes the system has swapped in from disk
++    (cumulative)
++  * **sout**: the number of bytes the system has swapped out from disk
++    (cumulative)
++
++  **sin** and **sout** on Windows are meaningless and are always set to ``0``.
++  See `examples/meminfo.py <https://github.com/giampaolo/psutil/blob/master/examples/meminfo.py>`__
++  script providing an example on how to convert bytes in a human readable form.
++
++    >>> import psutil
++    >>> psutil.swap_memory()
++    sswap(total=2097147904L, used=886620160L, free=1210527744L, percent=42.3, sin=1050411008, sout=1906720768)
++
++Disks
++-----
++
++.. function:: disk_partitions(all=False)
++
++  Return all mounted disk partitions as a list of namedtuples including device,
++  mount point and filesystem type, similarly to "df" command on UNIX. If *all*
++  parameter is ``False`` return physical devices only (e.g. hard disks, cd-rom
++  drives, USB keys) and ignore all others (e.g. memory partitions such as
++  `/dev/shm <http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html>`__).
++  Namedtuple's **fstype** field is a string which varies depending on the
++  platform.
++  On Linux it can be one of the values found in /proc/filesystems (e.g.
++  ``'ext3'`` for an ext3 hard drive o ``'iso9660'`` for the CD-ROM drive).
++  On Windows it is determined via
++  `GetDriveType <http://msdn.microsoft.com/en-us/library/aa364939(v=vs.85).aspx>`__
++  and can be either ``"removable"``, ``"fixed"``, ``"remote"``, ``"cdrom"``,
++  ``"unmounted"`` or ``"ramdisk"``. On OSX and FreeBSD it is retrieved via
++  `getfsstat(2) <http://www.manpagez.com/man/2/getfsstat/>`__. See
++  `disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
++  script providing an example usage.
++
++    >>> import psutil
++    >>> psutil.disk_partitions()
++    [sdiskpart(device='/dev/sda3', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro'),
++     sdiskpart(device='/dev/sda7', mountpoint='/home', fstype='ext4', opts='rw')]
++
++.. function:: disk_usage(path)
++
++  Return disk usage statistics about the given *path* as a namedtuple including
++  **total**, **used** and **free** space expressed in bytes, plus the
++  **percentage** usage.
++  `OSError <http://docs.python.org/3/library/exceptions.html#OSError>`__ is
++  raised if *path* does not exist. See
++  `examples/disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
++  script providing an example usage. Starting from
++  `Python 3.3 <http://bugs.python.org/issue12442>`__  this is also
++  available as
++  `shutil.disk_usage() <http://docs.python.org/3/library/shutil.html#shutil.disk_usage>`__.
++  See
++  `disk_usage.py <https://github.com/giampaolo/psutil/blob/master/examples/disk_usage.py>`__
++  script providing an example usage.
++
++    >>> import psutil
++    >>> psutil.disk_usage('/')
++    sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
++
++.. function:: disk_io_counters(perdisk=False)
++
++  Return system-wide disk I/O statistics as a namedtuple including the
++  following fields:
++
++  - **read_count**: number of reads
++  - **write_count**: number of writes
++  - **read_bytes**: number of bytes read
++  - **write_bytes**: number of bytes written
++  - **read_time**: time spent reading from disk (in milliseconds)
++  - **write_time**: time spent writing to disk (in milliseconds)
++
++  If *perdisk* is ``True`` return the same information for every physical disk
++  installed on the system as a dictionary with partition names as the keys and
++  the namedtuple described above as the values.
++  See `examples/iotop.py <https://github.com/giampaolo/psutil/blob/master/examples/iotop.py>`__
++  for an example application.
++
++    >>> import psutil
++    >>> psutil.disk_io_counters()
++    sdiskio(read_count=8141, write_count=2431, read_bytes=290203, write_bytes=537676, read_time=5868, write_time=94922)
++    >>>
++    >>> psutil.disk_io_counters(perdisk=True)
++    {'sda1': sdiskio(read_count=920, write_count=1, read_bytes=2933248, write_bytes=512, read_time=6016, write_time=4),
++     'sda2': sdiskio(read_count=18707, write_count=8830, read_bytes=6060, write_bytes=3443, read_time=24585, write_time=1572),
++     'sdb1': sdiskio(read_count=161, write_count=0, read_bytes=786432, write_bytes=0, read_time=44, write_time=0)}
++
++Network
++-------
++
++.. function:: net_io_counters(pernic=False)
++
++  Return system-wide network I/O statistics as a namedtuple including the
++  following attributes:
++
++  - **bytes_sent**: number of bytes sent
++  - **bytes_recv**: number of bytes received
++  - **packets_sent**: number of packets sent
++  - **packets_recv**: number of packets received
++  - **errin**: total number of errors while receiving
++  - **errout**: total number of errors while sending
++  - **dropin**: total number of incoming packets which were dropped
++  - **dropout**: total number of outgoing packets which were dropped (always 0
++    on OSX and BSD)
++
++  If *pernic* is ``True`` return the same information for every network
++  interface installed on the system as a dictionary with network interface
++  names as the keys and the namedtuple described above as the values.
++  See `examples/nettop.py <https://github.com/giampaolo/psutil/blob/master/examples/nettop.py>`__
++  for an example application.
++
++    >>> import psutil
++    >>> psutil.net_io_counters()
++    snetio(bytes_sent=14508483, bytes_recv=62749361, packets_sent=84311, packets_recv=94888, errin=0, errout=0, dropin=0, dropout=0)
++    >>>
++    >>> psutil.net_io_counters(pernic=True)
++    {'lo': snetio(bytes_sent=547971, bytes_recv=547971, packets_sent=5075, packets_recv=5075, errin=0, errout=0, dropin=0, dropout=0),
++    'wlan0': snetio(bytes_sent=13921765, bytes_recv=62162574, packets_sent=79097, packets_recv=89648, errin=0, errout=0, dropin=0, dropout=0)}
++
++.. function:: net_connections(kind='inet')
++
++  Return system-wide socket connections as a list of namedtuples.
++  Every namedtuple provides 7 attributes:
++
++  - **fd**: the socket file descriptor, if retrievable, else ``-1``.
++    If the connection refers to the current process this may be passed to
++    `socket.fromfd() <http://docs.python.org/library/socket.html#socket.fromfd>`__
++    to obtain a usable socket object.
++  - **family**: the address family, either `AF_INET
++    <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
++    `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
++    or `AF_UNIX <http://docs.python.org//library/socket.html#socket.AF_UNIX>`__.
++  - **type**: the address type, either `SOCK_STREAM
++    <http://docs.python.org//library/socket.html#socket.SOCK_STREAM>`__ or
++    `SOCK_DGRAM
++    <http://docs.python.org//library/socket.html#socket.SOCK_DGRAM>`__.
++  - **laddr**: the local address as a ``(ip, port)`` tuple or a ``path``
++    in case of AF_UNIX sockets.
++  - **raddr**: the remote address as a ``(ip, port)`` tuple or an absolute
++    ``path`` in case of UNIX sockets.
++    When the remote endpoint is not connected you'll get an empty tuple
++    (AF_INET*) or ``None`` (AF_UNIX).
++    On Linux AF_UNIX sockets will always have this set to ``None``.
++  - **status**: represents the status of a TCP connection. The return value
++    is one of the :data:`psutil.CONN_* <psutil.CONN_ESTABLISHED>` constants
++    (a string).
++    For UDP and UNIX sockets this is always going to be
++    :const:`psutil.CONN_NONE`.
++  - **pid**: the PID of the process which opened the socket, if retrievable,
++    else ``None``. On some platforms (e.g. Linux) the availability of this
++    field changes depending on process privileges (root is needed).
++
++  The *kind* parameter is a string which filters for connections that fit the
++  following criteria:
++
++  .. table::
++
++   +----------------+-----------------------------------------------------+
++   | **Kind value** | **Connections using**                               |
++   +================+=====================================================+
++   | "inet"         | IPv4 and IPv6                                       |
++   +----------------+-----------------------------------------------------+
++   | "inet4"        | IPv4                                                |
++   +----------------+-----------------------------------------------------+
++   | "inet6"        | IPv6                                                |
++   +----------------+-----------------------------------------------------+
++   | "tcp"          | TCP                                                 |
++   +----------------+-----------------------------------------------------+
++   | "tcp4"         | TCP over IPv4                                       |
++   +----------------+-----------------------------------------------------+
++   | "tcp6"         | TCP over IPv6                                       |
++   +----------------+-----------------------------------------------------+
++   | "udp"          | UDP                                                 |
++   +----------------+-----------------------------------------------------+
++   | "udp4"         | UDP over IPv4                                       |
++   +----------------+-----------------------------------------------------+
++   | "udp6"         | UDP over IPv6                                       |
++   +----------------+-----------------------------------------------------+
++   | "unix"         | UNIX socket (both UDP and TCP protocols)            |
++   +----------------+-----------------------------------------------------+
++   | "all"          | the sum of all the possible families and protocols  |
++   +----------------+-----------------------------------------------------+
++
++  On OSX this function requires root privileges.
++  To get per-process connections use :meth:`Process.connections`.
++  Also, see
++  `netstat.py sample script <https://github.com/giampaolo/psutil/blob/master/examples/netstat.py>`__.
++  Example:
++
++    >>> import psutil
++    >>> psutil.net_connections()
++    [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
++     pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
++     pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
++     pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
++     ...]
++
++  .. note:: (OSX) :class:`psutil.AccessDenied` is always raised unless running
++     as root (lsof does the same).
++  .. note:: (Solaris) UNIX sockets are not supported.
++
++  .. versionadded:: 2.1.0
++
++.. function:: net_if_addrs()
++
++  Return the addresses associated to each NIC (network interface card)
++  installed on the system as a dictionary whose keys are the NIC names and
++  value is a list of namedtuples for each address assigned to the NIC.
++  Each namedtuple includes 4 fields:
++
++  - **family**
++  - **address**
++  - **netmask**
++  - **broadcast**
++
++  *family* can be either
++  `AF_INET <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
++  `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
++  or :const:`psutil.AF_LINK`, which refers to a MAC address.
++  *address* is the primary address, *netmask* and *broadcast* may be ``None``.
++  Example::
++
++    >>> import psutil
++    >>> psutil.net_if_addrs()
++    {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
++            snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
++            snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
++     'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
++               snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
++               snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
++    >>>
++
++  See also `examples/ifconfig.py <https://github.com/giampaolo/psutil/blob/master/examples/ifconfig.py>`__
++  for an example application.
++
++  .. note:: if you're interested in others families (e.g. AF_BLUETOOTH) you can
++    use the more powerful `netifaces <https://pypi.python.org/pypi/netifaces/>`__
++    extension.
++
++  .. note:: you can have more than one address of the same family associated
++    with each interface (that's why dict values are lists).
++
++  *New in 3.0.0*
++
++.. function:: net_if_stats()
++
++  Return information about each NIC (network interface card) installed on the
++  system as a dictionary whose keys are the NIC names and value is a namedtuple
++  with the following fields:
++
++  - **isup**
++  - **duplex**
++  - **speed**
++  - **mtu**
++
++  *isup* is a boolean indicating whether the NIC is up and running, *duplex*
++  can be either :const:`NIC_DUPLEX_FULL`, :const:`NIC_DUPLEX_HALF` or
++  :const:`NIC_DUPLEX_UNKNOWN`, *speed* is the NIC speed expressed in mega bits
++  (MB), if it can't be determined (e.g. 'localhost') it will be set to ``0``,
++  *mtu* is the maximum transmission unit expressed in bytes.
++  See also `examples/ifconfig.py <https://github.com/giampaolo/psutil/blob/master/examples/ifconfig.py>`__
++  for an example application.
++  Example:
++
++    >>> import psutil
++    >>> psutil.net_if_stats()
++    {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
++     'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
++
++  *New in 3.0.0*
++
++
++Other system info
++-----------------
++
++.. function:: users()
++
++  Return users currently connected on the system as a list of namedtuples
++  including the following fields:
++
++  - **user**: the name of the user.
++  - **terminal**: the tty or pseudo-tty associated with the user, if any,
++    else ``None``.
++  - **host**: the host name associated with the entry, if any.
++  - **started**: the creation time as a floating point number expressed in
++    seconds since the epoch.
++
++  Example::
++
++    >>> import psutil
++    >>> psutil.users()
++    [suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
++     suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
++
++.. function:: boot_time()
++
++  Return the system boot time expressed in seconds since the epoch.
++  Example:
++
++  .. code-block:: python
++
++     >>> import psutil, datetime
++     >>> psutil.boot_time()
++     1389563460.0
++     >>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
++     '2014-01-12 22:51:00'
++
++Processes
++=========
++
++Functions
++---------
++
++.. function:: pids()
++
++  Return a list of current running PIDs. To iterate over all processes
++  :func:`process_iter()` should be preferred.
++
++.. function:: pid_exists(pid)
++
++  Check whether the given PID exists in the current process list. This is
++  faster than doing ``"pid in psutil.pids()"`` and should be preferred.
++
++.. function:: process_iter()
++
++  Return an iterator yielding a :class:`Process` class instance for all running
++  processes on the local machine.
++  Every instance is only created once and then cached into an internal table
++  which is updated every time an element is yielded.
++  Cached :class:`Process` instances are checked for identity so that you're
++  safe in case a PID has been reused by another process, in which case the
++  cached instance is updated.
++  This is should be preferred over :func:`psutil.pids()` for iterating over
++  processes.
++  Sorting order in which processes are returned is
++  based on their PID. Example usage::
++
++    import psutil
++
++    for proc in psutil.process_iter():
++        try:
++            pinfo = proc.as_dict(attrs=['pid', 'name'])
++        except psutil.NoSuchProcess:
++            pass
++        else:
++            print(pinfo)
++
++.. function:: wait_procs(procs, timeout=None, callback=None)
++
++  Convenience function which waits for a list of :class:`Process` instances to
++  terminate. Return a ``(gone, alive)`` tuple indicating which processes are
++  gone and which ones are still alive. The *gone* ones will have a new
++  *returncode* attribute indicating process exit status (it may be ``None``).
++  ``callback`` is a function which gets called every time a process terminates
++  (a :class:`Process` instance is passed as callback argument). Function will
++  return as soon as all processes terminate or when timeout occurs. Tipical use
++  case is:
++
++  - send SIGTERM to a list of processes
++  - give them some time to terminate
++  - send SIGKILL to those ones which are still alive
++
++  Example::
++
++    import psutil
++
++    def on_terminate(proc):
++        print("process {} terminated with exit code {}".format(proc, proc.returncode))
++
++    procs = [...]  # a list of Process instances
++    for p in procs:
++        p.terminate()
++    gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
++    for p in alive:
++        p.kill()
++
++Exceptions
++----------
++
++.. class:: Error()
++
++  Base exception class. All other exceptions inherit from this one.
++
++.. class:: NoSuchProcess(pid, name=None, msg=None)
++
++   Raised by :class:`Process` class methods when no process with the given
++   *pid* is found in the current process list or when a process no longer
++   exists. "name" is the name the process had before disappearing
++   and gets set only if :meth:`Process.name()` was previosly called.
++
++.. class:: ZombieProcess(pid, name=None, ppid=None, msg=None)
++
++   This may be raised by :class:`Process` class methods when querying a zombie
++   process on UNIX (Windows doesn't have zombie processes). Depending on the
++   method called the OS may be able to succeed in retrieving the process
++   information or not.
++   Note: this is a subclass of :class:`NoSuchProcess` so if you're not
++   interested in retrieving zombies while iterating over all processes (e.g.
++   via :func:`process_iter()`) you can ignore this exception and just catch
++   :class:`NoSuchProcess`.
++
++   *New in 3.0.0*
++
++.. class:: AccessDenied(pid=None, name=None, msg=None)
++
++    Raised by :class:`Process` class methods when permission to perform an
++    action is denied. "name" is the name of the process (may be ``None``).
++
++.. class:: TimeoutExpired(seconds, pid=None, name=None, msg=None)
++
++    Raised by :meth:`Process.wait` if timeout expires and process is still
++    alive.
++
++Process class
++-------------
++
++.. class:: Process(pid=None)
++
++  Represents an OS process with the given *pid*. If *pid* is omitted current
++  process *pid* (`os.getpid() <http://docs.python.org/library/os.html#os.getpid>`__)
++  is used.
++  Raise :class:`NoSuchProcess` if *pid* does not exist.
++  When accessing methods of this class always be  prepared to catch
++  :class:`NoSuchProcess` and :class:`AccessDenied` exceptions.
++  `hash() <http://docs.python.org/2/library/functions.html#hash>`__ builtin can
++  be used against instances of this class in order to identify a process
++  univocally over time (the hash is determined by mixing process PID
++  and creation time). As such it can also be used with
++  `set()s <http://docs.python.org/2/library/stdtypes.html#types-set>`__.
++
++  .. warning::
++
++    the way this class is bound to a process is uniquely via its **PID**.
++    That means that if the :class:`Process` instance is old enough and
++    the PID has been reused by another process in the meantime you might end up
++    interacting with another process.
++    The only exceptions for which process identity is pre-emptively checked
++    (via PID + creation time) and guaranteed are for
++    :meth:`nice` (set),
++    :meth:`ionice`  (set),
++    :meth:`cpu_affinity` (set),
++    :meth:`rlimit` (set),
++    :meth:`children`,
++    :meth:`parent`,
++    :meth:`suspend`
++    :meth:`resume`,
++    :meth:`send_signal`,
++    :meth:`terminate`, and
++    :meth:`kill`
++    methods.
++    To prevent this problem for all other methods you can use
++    :meth:`is_running()` before querying the process or use
++    :func:`process_iter()` in case you're iterating over all processes.
++
++  .. attribute:: pid
++
++     The process PID.
++
++  .. method:: ppid()
++
++     The process parent pid.  On Windows the return value is cached after first
++     call.
++
++  .. method:: name()
++
++     The process name. The return value is cached after first call.
++
++  .. method:: exe()
++
++     The process executable as an absolute path.
++     On some systems this may also be an empty string.
++     The return value is cached after first call.
++
++  .. method:: cmdline()
++
++     The command line this process has been called with.
++
++  .. method:: create_time()
++
++     The process creation time as a floating point number expressed in seconds
++     since the epoch, in
++     `UTC <http://en.wikipedia.org/wiki/Coordinated_universal_time>`__.
++     The return value is cached after first call.
++
++        >>> import psutil, datetime
++        >>> p = psutil.Process()
++        >>> p.create_time()
++        1307289803.47
++        >>> datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S")
++        '2011-03-05 18:03:52'
++
++  .. method:: as_dict(attrs=None, ad_value=None)
++
++     Utility method returning process information as a hashable dictionary.
++     If *attrs* is specified it must be a list of strings reflecting available
++     :class:`Process` class's attribute names (e.g. ``['cpu_times', 'name']``)
++     else all public (read only) attributes are assumed. *ad_value* is the
++     value which gets assigned to a dict key in case :class:`AccessDenied`
++     or :class:`ZombieProcess` exception is raised when retrieving that
++     particular process information.
++
++        >>> import psutil
++        >>> p = psutil.Process()
++        >>> p.as_dict(attrs=['pid', 'name', 'username'])
++        {'username': 'giampaolo', 'pid': 12366, 'name': 'python'}
++
++     .. versionchanged:: 3.0.0 *ad_value* is used also when incurring into
++        :class:`ZombieProcess` exception, not only :class:`AccessDenied`
++
++  .. method:: parent()
++
++     Utility method which returns the parent process as a :class:`Process`
++     object pre-emptively checking whether PID has been reused. If no parent
++     PID is known return ``None``.
++
++  .. method:: status()
++
++     The current process status as a string. The returned string is one of the
++     :data:`psutil.STATUS_*<psutil.STATUS_RUNNING>` constants.
++
++  .. method:: cwd()
++
++     The process current working directory as an absolute path.
++
++  .. method:: username()
++
++     The name of the user that owns the process. On UNIX this is calculated by
++     using real process uid.
++
++  .. method:: uids()
++
++     The **real**, **effective** and **saved** user ids of this process as a
++     namedtuple. This is the same as
++     `os.getresuid() <http://docs.python.org//library/os.html#os.getresuid>`__
++     but can be used for every process PID.
++
++     Availability: UNIX
++
++  .. method:: gids()
++
++     The **real**, **effective** and **saved** group ids of this process as a
++     namedtuple. This is the same as
++     `os.getresgid() <http://docs.python.org//library/os.html#os.getresgid>`__
++     but can be used for every process PID.
++
++     Availability: UNIX
++
++  .. method:: terminal()
++
++     The terminal associated with this process, if any, else ``None``. This is
++     similar to "tty" command but can be used for every process PID.
++
++     Availability: UNIX
++
++  .. method:: nice(value=None)
++
++     Get or set process
++     `niceness <blogs.techrepublic.com.com/opensource/?p=140>`__ (priority).
++     On UNIX this is a number which usually goes from ``-20`` to ``20``.
++     The higher the nice value, the lower the priority of the process.
++
++        >>> import psutil
++        >>> p = psutil.Process()
++        >>> p.nice(10)  # set
++        >>> p.nice()  # get
++        10
++        >>>
++
++     Starting from `Python 3.3 <http://bugs.python.org/issue10784>`__ this
++     functionality is also available as
++     `os.getpriority() <http://docs.python.org/3/library/os.html#os.getpriority>`__
++     and
++     `os.setpriority() <http://docs.python.org/3/library/os.html#os.setpriority>`__
++     (UNIX only).
++
++     On Windows this is available as well by using
++     `GetPriorityClass <http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx>`__
++     and `SetPriorityClass <http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx>`__
++     and *value* is one of the
++     :data:`psutil.*_PRIORITY_CLASS <psutil.ABOVE_NORMAL_PRIORITY_CLASS>`
++     constants.
++     Example which increases process priority on Windows:
++
++        >>> p.nice(psutil.HIGH_PRIORITY_CLASS)
++
++  .. method:: ionice(ioclass=None, value=None)
++
++     Get or set
++     `process I/O niceness <http://friedcpu.wordpress.com/2007/07/17/why-arent-you-using-ionice-yet/>`__ (priority).
++     On Linux *ioclass* is one of the
++     :data:`psutil.IOPRIO_CLASS_*<psutil.IOPRIO_CLASS_NONE>` constants.
++     *value* is a number which goes from  ``0`` to ``7``. The higher the value,
++     the lower the I/O priority of the process. On Windows only *ioclass* is
++     used and it can be set to ``2`` (normal), ``1`` (low) or ``0`` (very low).
++     The example below sets IDLE priority class for the current process,
++     meaning it will only get I/O time when no other process needs the disk:
++
++      >>> import psutil
++      >>> p = psutil.Process()
++      >>> p.ionice(psutil.IOPRIO_CLASS_IDLE)  # set
++      >>> p.ionice()  # get
++      pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
++      >>>
++
++     On Windows only *ioclass* is used and it can be set to ``2`` (normal),
++     ``1`` (low) or ``0`` (very low).
++
++     Availability: Linux and Windows > Vista
++
++     .. versionchanged:: 3.0.0 on >= Python 3.4 the returned ``ioclass``
++        constant is an `enum <https://docs.python.org/3/library/enum.html#module-enum>`__
++        instead of a plain integer.
++
++  .. method:: rlimit(resource, limits=None)
++
++     Get or set process resource limits (see
++     `man prlimit <http://linux.die.net/man/2/prlimit>`__). *resource* is one of
++     the :data:`psutil.RLIMIT_* <psutil.RLIMIT_INFINITY>` constants.
++     *limits* is a ``(soft, hard)`` tuple.
++     This is the same as `resource.getrlimit() <http://docs.python.org/library/resource.html#resource.getrlimit>`__
++     and `resource.setrlimit() <http://docs.python.org/library/resource.html#resource.setrlimit>`__
++     but can be used for every process PID and only on Linux.
++     Example:
++
++      >>> import psutil
++      >>> p = psutil.Process()
++      >>> # process may open no more than 128 file descriptors
++      >>> p.rlimit(psutil.RLIMIT_NOFILE, (128, 128))
++      >>> # process may create files no bigger than 1024 bytes
++      >>> p.rlimit(psutil.RLIMIT_FSIZE, (1024, 1024))
++      >>> # get
++      >>> p.rlimit(psutil.RLIMIT_FSIZE)
++      (1024, 1024)
++      >>>
++
++     Availability: Linux
++
++  .. method:: io_counters()
++
++     Return process I/O statistics as a namedtuple including the number of read
++     and write operations performed by the process and the amount of bytes read
++     and written. For Linux refer to
++     `/proc filesysem documentation <https://www.kernel.org/doc/Documentation/filesystems/proc.txt>`__.
++     On BSD there's apparently no way to retrieve bytes counters, hence ``-1``
++     is returned for **read_bytes** and **write_bytes** fields. OSX is not
++     supported.
++
++      >>> import psutil
++      >>> p = psutil.Process()
++      >>> p.io_counters()
++      pio(read_count=454556, write_count=3456, read_bytes=110592, write_bytes=0)
++
++     Availability: all platforms except OSX and Solaris
++
++  .. method:: num_ctx_switches()
++
++     The number voluntary and involuntary context switches performed by
++     this process.
++
++  .. method:: num_fds()
++
++     The number of file descriptors used by this process.
++
++     Availability: UNIX
++
++  .. method:: num_handles()
++
++     The number of handles used by this process.
++
++     Availability: Windows
++
++  .. method:: num_threads()
++
++     The number of threads currently used by this process.
++
++  .. method:: threads()
++
++     Return threads opened by process as a list of namedtuples including thread
++     id and thread CPU times (user/system).
++
++  .. method:: cpu_times()
++
++     Return a tuple whose values are process CPU **user** and **system**
++     times which means the amount of time expressed in seconds that a process
++     has spent in
++     `user / system mode <http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1>`__.
++     This is similar to
++     `os.times() <http://docs.python.org//library/os.html#os.times>`__
++     but can be used for every process PID.
++
++  .. method:: cpu_percent(interval=None)
++
++     Return a float representing the process CPU utilization as a percentage.
++     When *interval* is > ``0.0`` compares process times to system CPU times
++     elapsed before and after the interval (blocking). When interval is ``0.0``
++     or ``None`` compares process times to system CPU times elapsed since last
++     call, returning immediately. That means the first time this is called it
++     will return a meaningless ``0.0`` value which you are supposed to ignore.
++     In this case is recommended for accuracy that this function be called a
++     second time with at least ``0.1`` seconds between calls. Example:
++
++      >>> import psutil
++      >>> p = psutil.Process()
++      >>>
++      >>> # blocking
++      >>> p.cpu_percent(interval=1)
++      2.0
++      >>> # non-blocking (percentage since last call)
++      >>> p.cpu_percent(interval=None)
++      2.9
++      >>>
++
++     .. note::
++        a percentage > 100 is legitimate as it can result from a process with
++        multiple threads running on different CPU cores.
++
++     .. warning::
++        the first time this method is called with interval = ``0.0`` or
++        ``None`` it will return a meaningless ``0.0`` value which you are
++        supposed to ignore.
++
++  .. method:: cpu_affinity(cpus=None)
++
++     Get or set process current
++     `CPU affinity <http://www.linuxjournal.com/article/6799?page=0,0>`__.
++     CPU affinity consists in telling the OS to run a certain process on a
++     limited set of CPUs only. The number of eligible CPUs can be obtained with
++     ``list(range(psutil.cpu_count()))``. On set raises ``ValueError`` in case
++     an invalid CPU number is specified.
++
++      >>> import psutil
++      >>> psutil.cpu_count()
++      4
++      >>> p = psutil.Process()
++      >>> p.cpu_affinity()  # get
++      [0, 1, 2, 3]
++      >>> p.cpu_affinity([0])  # set; from now on, process will run on CPU #0 only
++      >>> p.cpu_affinity()
++      [0]
++      >>>
++      >>> # reset affinity against all CPUs
++      >>> all_cpus = list(range(psutil.cpu_count()))
++      >>> p.cpu_affinity(all_cpus)
++      >>>
++
++     Availability: Linux, Windows, BSD
++
++     .. versionchanged:: 2.2.0 added support for FreeBSD
++
++  .. method:: memory_info()
++
++     Return a tuple representing RSS (Resident Set Size) and VMS (Virtual
++     Memory Size) in bytes. On UNIX *rss* and *vms* are the same values shown
++     by ps. On Windows *rss* and *vms* refer to "Mem Usage" and "VM Size"
++     columns of taskmgr.exe. For more detailed memory stats use
++     :meth:`memory_info_ex`.
++
++  .. method:: memory_info_ex()
++
++     Return a namedtuple with variable fields depending on the platform
++     representing extended memory information about the process.
++     All numbers are expressed in bytes.
++
++     +--------+---------+-------+-------+--------------------+
++     | Linux  | OSX     | BSD   | SunOS | Windows            |
++     +========+=========+=======+=======+====================+
++     | rss    | rss     | rss   | rss   | num_page_faults    |
++     +--------+---------+-------+-------+--------------------+
++     | vms    | vms     | vms   | vms   | peak_wset          |
++     +--------+---------+-------+-------+--------------------+
++     | shared | pfaults | text  |       | wset               |
++     +--------+---------+-------+-------+--------------------+
++     | text   | pageins | data  |       | peak_paged_pool    |
++     +--------+---------+-------+-------+--------------------+
++     | lib    |         | stack |       | paged_pool         |
++     +--------+---------+-------+-------+--------------------+
++     | data   |         |       |       | peak_nonpaged_pool |
++     +--------+---------+-------+-------+--------------------+
++     | dirty  |         |       |       | nonpaged_pool      |
++     +--------+---------+-------+-------+--------------------+
++     |        |         |       |       | pagefile           |
++     +--------+---------+-------+-------+--------------------+
++     |        |         |       |       | peak_pagefile      |
++     +--------+---------+-------+-------+--------------------+
++     |        |         |       |       | private            |
++     +--------+---------+-------+-------+--------------------+
++
++     Windows metrics are extracted from
++     `PROCESS_MEMORY_COUNTERS_EX <http://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx>`__ structure.
++     Example on Linux:
++
++     >>> import psutil
++     >>> p = psutil.Process()
++     >>> p.memory_info_ex()
++     pextmem(rss=15491072, vms=84025344, shared=5206016, text=2555904, lib=0, data=9891840, dirty=0)
++
++  .. method:: memory_percent()
++
++     Compare physical system memory to process resident memory (RSS) and
++     calculate process memory utilization as a percentage.
++
++  .. method:: memory_maps(grouped=True)
++
++     Return process's mapped memory regions as a list of namedtuples whose
++     fields are variable depending on the platform. As such, portable
++     applications should rely on namedtuple's `path` and `rss` fields only.
++     This method is useful to obtain a detailed representation of process
++     memory usage as explained
++     `here <http://bmaurer.blogspot.it/2006/03/memory-usage-with-smaps.html>`__.
++     If *grouped* is ``True`` the mapped regions with the same *path* are
++     grouped together and the different memory fields are summed.  If *grouped*
++     is ``False`` every mapped region is shown as a single entity and the
++     namedtuple will also include the mapped region's address space (*addr*)
++     and permission set (*perms*).
++     See `examples/pmap.py <https://github.com/giampaolo/psutil/blob/master/examples/pmap.py>`__
++     for an example application.
++
++      >>> import psutil
++      >>> p = psutil.Process()
++      >>> p.memory_maps()
++      [pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
++       pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
++       pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, anonymous=1245, swap=0),
++       pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0),
++       pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0),
++       ...]
++      >>>
++
++  .. method:: children(recursive=False)
++
++     Return the children of this process as a list of :Class:`Process` objects,
++     pre-emptively checking whether PID has been reused. If recursive is `True`
++     return all the parent descendants.
++     Example assuming *A == this process*:
++     ::
++
++          A ─┐
++             │
++             ├─ B (child) ─┐
++             │             └─ X (grandchild) ─┐
++             │                                └─ Y (great grandchild)
++             ├─ C (child)
++             └─ D (child)
++
++          >>> p.children()
++          B, C, D
++          >>> p.children(recursive=True)
++          B, X, Y, C, D
++
++     Note that in the example above if process X disappears process Y won't be
++     returned either as the reference to process A is lost.
++
++  .. method:: open_files()
++
++     Return regular files opened by process as a list of namedtuples including
++     the absolute file name and the file descriptor number (on Windows this is
++     always ``-1``). Example:
++
++      >>> import psutil
++      >>> f = open('file.ext', 'w')
++      >>> p = psutil.Process()
++      >>> p.open_files()
++      [popenfile(path='/home/giampaolo/svn/psutil/file.ext', fd=3)]
++
++  .. method:: connections(kind="inet")
++
++    Return socket connections opened by process as a list of namedtuples.
++    To get system-wide connections use :func:`psutil.net_connections()`.
++    Every namedtuple provides 6 attributes:
++
++    - **fd**: the socket file descriptor. This can be passed to
++      `socket.fromfd() <http://docs.python.org/library/socket.html#socket.fromfd>`__
++      to obtain a usable socket object.
++      This is only available on UNIX; on Windows ``-1`` is always returned.
++    - **family**: the address family, either `AF_INET
++      <http://docs.python.org//library/socket.html#socket.AF_INET>`__,
++      `AF_INET6 <http://docs.python.org//library/socket.html#socket.AF_INET6>`__
++      or `AF_UNIX <http://docs.python.org//library/socket.html#socket.AF_UNIX>`__.
++    - **type**: the address type, either `SOCK_STREAM
++      <http://docs.python.org//library/socket.html#socket.SOCK_STREAM>`__ or
++      `SOCK_DGRAM
++      <http://docs.python.org//library/socket.html#socket.SOCK_DGRAM>`__.
++    - **laddr**: the local address as a ``(ip, port)`` tuple or a ``path``
++      in case of AF_UNIX sockets.
++    - **raddr**: the remote address as a ``(ip, port)`` tuple or an absolute
++      ``path`` in case of UNIX sockets.
++      When the remote endpoint is not connected you'll get an empty tuple
++      (AF_INET) or ``None`` (AF_UNIX).
++      On Linux AF_UNIX sockets will always have this set to ``None``.
++    - **status**: represents the status of a TCP connection. The return value
++      is one of the :data:`psutil.CONN_* <psutil.CONN_ESTABLISHED>` constants.
++      For UDP and UNIX sockets this is always going to be
++      :const:`psutil.CONN_NONE`.
++
++    The *kind* parameter is a string which filters for connections that fit the
++    following criteria:
++
++    .. table::
++
++     +----------------+-----------------------------------------------------+
++     | **Kind value** | **Connections using**                               |
++     +================+=====================================================+
++     | "inet"         | IPv4 and IPv6                                       |
++     +----------------+-----------------------------------------------------+
++     | "inet4"        | IPv4                                                |
++     +----------------+-----------------------------------------------------+
++     | "inet6"        | IPv6                                                |
++     +----------------+-----------------------------------------------------+
++     | "tcp"          | TCP                                                 |
++     +----------------+-----------------------------------------------------+
++     | "tcp4"         | TCP over IPv4                                       |
++     +----------------+-----------------------------------------------------+
++     | "tcp6"         | TCP over IPv6                                       |
++     +----------------+-----------------------------------------------------+
++     | "udp"          | UDP                                                 |
++     +----------------+-----------------------------------------------------+
++     | "udp4"         | UDP over IPv4                                       |
++     +----------------+-----------------------------------------------------+
++     | "udp6"         | UDP over IPv6                                       |
++     +----------------+-----------------------------------------------------+
++     | "unix"         | UNIX socket (both UDP and TCP protocols)            |
++     +----------------+-----------------------------------------------------+
++     | "all"          | the sum of all the possible families and protocols  |
++     +----------------+-----------------------------------------------------+
++
++    Example:
++
++      >>> import psutil
++      >>> p = psutil.Process(1694)
++      >>> p.name()
++      'firefox'
++      >>> p.connections()
++      [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
++       pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
++       pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
++       pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
++
++  .. method:: is_running()
++
++     Return whether the current process is running in the current process list.
++     This is reliable also in case the process is gone and its PID reused by
++     another process, therefore it must be preferred over doing
++     ``psutil.pid_exists(p.pid)``.
++
++     .. note::
++      this will return ``True`` also if the process is a zombie
++      (``p.status() == psutil.STATUS_ZOMBIE``).
++
++  .. method:: send_signal(signal)
++
++     Send a signal to process (see
++     `signal module <http://docs.python.org//library/signal.html>`__
++     constants) pre-emptively checking whether PID has been reused.
++     This is the same as ``os.kill(pid, sig)``.
++     On Windows only **SIGTERM** is valid and is treated as an alias for
++     :meth:`kill()`.
++
++  .. method:: suspend()
++
++     Suspend process execution with **SIGSTOP** signal pre-emptively checking
++     whether PID has been reused.
++     On UNIX this is the same as ``os.kill(pid, signal.SIGSTOP)``.
++     On Windows this is done by suspending all process threads execution.
++
++  .. method:: resume()
++
++     Resume process execution with **SIGCONT** signal pre-emptively checking
++     whether PID has been reused.
++     On UNIX this is the same as ``os.kill(pid, signal.SIGCONT)``.
++     On Windows this is done by resuming all process threads execution.
++
++  .. method:: terminate()
++
++     Terminate the process with **SIGTERM** signal pre-emptively checking
++     whether PID has been reused.
++     On UNIX this is the same as ``os.kill(pid, signal.SIGTERM)``.
++     On Windows this is an alias for :meth:`kill`.
++
++  .. method:: kill()
++
++     Kill the current process by using **SIGKILL** signal pre-emptively
++     checking whether PID has been reused.
++     On UNIX this is the same as ``os.kill(pid, signal.SIGKILL)``.
++     On Windows this is done by using
++     `TerminateProcess <http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx>`__.
++
++  .. method:: wait(timeout=None)
++
++     Wait for process termination and if the process is a children of the
++     current one also return the exit code, else ``None``. On Windows there's
++     no such limitation (exit code is always returned). If the process is
++     already terminated immediately return ``None`` instead of raising
++     :class:`NoSuchProcess`. If *timeout* is specified and process is still
++     alive raise :class:`TimeoutExpired` exception. It can also be used in a
++     non-blocking fashion by specifying ``timeout=0`` in which case it will
++     either return immediately or raise :class:`TimeoutExpired`.
++     To wait for multiple processes use :func:`psutil.wait_procs()`.
++
++
++Popen class
++-----------
++
++.. class:: Popen(*args, **kwargs)
++
++  A more convenient interface to stdlib
++  `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__.
++  It starts a sub process and deals with it exactly as when using
++  `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__
++  but in addition it also provides all the methods of
++  :class:`psutil.Process` class in a single interface.
++  For method names common to both classes such as
++  :meth:`send_signal() <psutil.Process.send_signal()>`,
++  :meth:`terminate() <psutil.Process.terminate()>` and
++  :meth:`kill() <psutil.Process.kill()>`
++  :class:`psutil.Process` implementation takes precedence.
++  For a complete documentation refer to
++  `subprocess module documentation <http://docs.python.org/library/subprocess.html>`__.
++
++  .. note::
++
++     Unlike `subprocess.Popen <http://docs.python.org/library/subprocess.html#subprocess.Popen>`__
++     this class pre-emptively checks wheter PID has been reused on
++     :meth:`send_signal() <psutil.Process.send_signal()>`,
++     :meth:`terminate() <psutil.Process.terminate()>` and
++     :meth:`kill() <psutil.Process.kill()>`
++     so that you can't accidentally terminate another process, fixing
++     http://bugs.python.org/issue6973.
++
++  >>> import psutil
++  >>> from subprocess import PIPE
++  >>>
++  >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
++  >>> p.name()
++  'python'
++  >>> p.username()
++  'giampaolo'
++  >>> p.communicate()
++  ('hello\n', None)
++  >>> p.wait(timeout=2)
++  0
++  >>>
++
++Constants
++=========
++
++.. _const-pstatus:
++.. data:: STATUS_RUNNING
++          STATUS_SLEEPING
++          STATUS_DISK_SLEEP
++          STATUS_STOPPED
++          STATUS_TRACING_STOP
++          STATUS_ZOMBIE
++          STATUS_DEAD
++          STATUS_WAKE_KILL
++          STATUS_WAKING
++          STATUS_IDLE
++          STATUS_LOCKED
++          STATUS_WAITING
++
++  A set of strings representing the status of a process.
++  Returned by :meth:`psutil.Process.status()`.
++
++.. _const-conn:
++.. data:: CONN_ESTABLISHED
++          CONN_SYN_SENT
++          CONN_SYN_RECV
++          CONN_FIN_WAIT1
++          CONN_FIN_WAIT2
++          CONN_TIME_WAIT
++          CONN_CLOSE
++          CONN_CLOSE_WAIT
++          CONN_LAST_ACK
++          CONN_LISTEN
++          CONN_CLOSING
++          CONN_NONE
++          CONN_DELETE_TCB (Windows)
++          CONN_IDLE (Solaris)
++          CONN_BOUND (Solaris)
++
++  A set of strings representing the status of a TCP connection.
++  Returned by :meth:`psutil.Process.connections()` (`status` field).
++
++.. _const-prio:
++.. data:: ABOVE_NORMAL_PRIORITY_CLASS
++          BELOW_NORMAL_PRIORITY_CLASS
++          HIGH_PRIORITY_CLASS
++          IDLE_PRIORITY_CLASS
++          NORMAL_PRIORITY_CLASS
++          REALTIME_PRIORITY_CLASS
++
++  A set of integers representing the priority of a process on Windows (see
++  `MSDN documentation <http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx>`__).
++  They can be used in conjunction with
++  :meth:`psutil.Process.nice()` to get or set process priority.
++
++  Availability: Windows
++
++  .. versionchanged:: 3.0.0 on Python >= 3.4 these constants are
++    `enums <https://docs.python.org/3/library/enum.html#module-enum>`__
++    instead of a plain integer.
++
++.. _const-ioprio:
++.. data:: IOPRIO_CLASS_NONE
++          IOPRIO_CLASS_RT
++          IOPRIO_CLASS_BE
++          IOPRIO_CLASS_IDLE
++
++  A set of integers representing the I/O priority of a process on Linux. They
++  can be used in conjunction with :meth:`psutil.Process.ionice()` to get or set
++  process I/O priority.
++  *IOPRIO_CLASS_NONE* and *IOPRIO_CLASS_BE* (best effort) is the default for
++  any process that hasn't set a specific I/O priority.
++  *IOPRIO_CLASS_RT* (real time) means the process is given first access to the
++  disk, regardless of what else is going on in the system.
++  *IOPRIO_CLASS_IDLE* means the process will get I/O time when no-one else
++  needs the disk.
++  For further information refer to manuals of
++  `ionice <http://linux.die.net/man/1/ionice>`__
++  command line utility or
++  `ioprio_get <http://linux.die.net/man/2/ioprio_get>`__
++  system call.
++
++  Availability: Linux
++
++  .. versionchanged:: 3.0.0 on Python >= 3.4 thse constants are
++    `enums <https://docs.python.org/3/library/enum.html#module-enum>`__
++    instead of a plain integer.
++
++.. _const-rlimit:
++.. data:: RLIMIT_INFINITY
++          RLIMIT_AS
++          RLIMIT_CORE
++          RLIMIT_CPU
++          RLIMIT_DATA
++          RLIMIT_FSIZE
++          RLIMIT_LOCKS
++          RLIMIT_MEMLOCK
++          RLIMIT_MSGQUEUE
++          RLIMIT_NICE
++          RLIMIT_NOFILE
++          RLIMIT_NPROC
++          RLIMIT_RSS
++          RLIMIT_RTPRIO
++          RLIMIT_RTTIME
++          RLIMIT_RTPRIO
++          RLIMIT_SIGPENDING
++          RLIMIT_STACK
++
++  Constants used for getting and setting process resource limits to be used in
++  conjunction with :meth:`psutil.Process.rlimit()`. See
++  `man prlimit <http://linux.die.net/man/2/prlimit>`__ for futher information.
++
++  Availability: Linux
++
++.. _const-aflink:
++.. data:: AF_LINK
++
++  Constant which identifies a MAC address associated with a network interface.
++  To be used in conjunction with :func:`psutil.net_if_addrs()`.
++
++  *New in 3.0.0*
++
++.. _const-duplex:
++.. data:: NIC_DUPLEX_FULL
++          NIC_DUPLEX_HALF
++          NIC_DUPLEX_UNKNOWN
++
++  Constants which identifies whether a NIC (network interface card) has full or
++  half mode speed.  NIC_DUPLEX_FULL means the NIC is able to send and receive
++  data (files) simultaneously, NIC_DUPLEX_FULL means the NIC can either send or
++  receive data at a time.
++  To be used in conjunction with :func:`psutil.net_if_stats()`.
++
++  *New in 3.0.0*
+--- mozjs-24.2.0/js/src/python/psutil/docs/make.bat	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/make.bat	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,242 @@
++@ECHO OFF
++
++REM Command file for Sphinx documentation
++
++if "%SPHINXBUILD%" == "" (
++	set SPHINXBUILD=sphinx-build
++)
++set BUILDDIR=_build
++set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
++set I18NSPHINXOPTS=%SPHINXOPTS% .
++if NOT "%PAPER%" == "" (
++	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
++	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
++)
++
++if "%1" == "" goto help
++
++if "%1" == "help" (
++	:help
++	echo.Please use `make ^<target^>` where ^<target^> is one of
++	echo.  html       to make standalone HTML files
++	echo.  dirhtml    to make HTML files named index.html in directories
++	echo.  singlehtml to make a single large HTML file
++	echo.  pickle     to make pickle files
++	echo.  json       to make JSON files
++	echo.  htmlhelp   to make HTML files and a HTML help project
++	echo.  qthelp     to make HTML files and a qthelp project
++	echo.  devhelp    to make HTML files and a Devhelp project
++	echo.  epub       to make an epub
++	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
++	echo.  text       to make text files
++	echo.  man        to make manual pages
++	echo.  texinfo    to make Texinfo files
++	echo.  gettext    to make PO message catalogs
++	echo.  changes    to make an overview over all changed/added/deprecated items
++	echo.  xml        to make Docutils-native XML files
++	echo.  pseudoxml  to make pseudoxml-XML files for display purposes
++	echo.  linkcheck  to check all external links for integrity
++	echo.  doctest    to run all doctests embedded in the documentation if enabled
++	goto end
++)
++
++if "%1" == "clean" (
++	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
++	del /q /s %BUILDDIR%\*
++	goto end
++)
++
++
++%SPHINXBUILD% 2> nul
++if errorlevel 9009 (
++	echo.
++	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
++	echo.installed, then set the SPHINXBUILD environment variable to point
++	echo.to the full path of the 'sphinx-build' executable. Alternatively you
++	echo.may add the Sphinx directory to PATH.
++	echo.
++	echo.If you don't have Sphinx installed, grab it from
++	echo.http://sphinx-doc.org/
++	exit /b 1
++)
++
++if "%1" == "html" (
++	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
++	goto end
++)
++
++if "%1" == "dirhtml" (
++	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
++	goto end
++)
++
++if "%1" == "singlehtml" (
++	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
++	goto end
++)
++
++if "%1" == "pickle" (
++	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished; now you can process the pickle files.
++	goto end
++)
++
++if "%1" == "json" (
++	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished; now you can process the JSON files.
++	goto end
++)
++
++if "%1" == "htmlhelp" (
++	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished; now you can run HTML Help Workshop with the ^
++.hhp project file in %BUILDDIR%/htmlhelp.
++	goto end
++)
++
++if "%1" == "qthelp" (
++	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished; now you can run "qcollectiongenerator" with the ^
++.qhcp project file in %BUILDDIR%/qthelp, like this:
++	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\psutil.qhcp
++	echo.To view the help file:
++	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\psutil.ghc
++	goto end
++)
++
++if "%1" == "devhelp" (
++	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished.
++	goto end
++)
++
++if "%1" == "epub" (
++	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The epub file is in %BUILDDIR%/epub.
++	goto end
++)
++
++if "%1" == "latex" (
++	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
++	goto end
++)
++
++if "%1" == "latexpdf" (
++	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
++	cd %BUILDDIR%/latex
++	make all-pdf
++	cd %BUILDDIR%/..
++	echo.
++	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
++	goto end
++)
++
++if "%1" == "latexpdfja" (
++	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
++	cd %BUILDDIR%/latex
++	make all-pdf-ja
++	cd %BUILDDIR%/..
++	echo.
++	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
++	goto end
++)
++
++if "%1" == "text" (
++	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The text files are in %BUILDDIR%/text.
++	goto end
++)
++
++if "%1" == "man" (
++	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The manual pages are in %BUILDDIR%/man.
++	goto end
++)
++
++if "%1" == "texinfo" (
++	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
++	goto end
++)
++
++if "%1" == "gettext" (
++	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
++	goto end
++)
++
++if "%1" == "changes" (
++	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.The overview file is in %BUILDDIR%/changes.
++	goto end
++)
++
++if "%1" == "linkcheck" (
++	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Link check complete; look for any errors in the above output ^
++or in %BUILDDIR%/linkcheck/output.txt.
++	goto end
++)
++
++if "%1" == "doctest" (
++	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Testing of doctests in the sources finished, look at the ^
++results in %BUILDDIR%/doctest/output.txt.
++	goto end
++)
++
++if "%1" == "xml" (
++	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The XML files are in %BUILDDIR%/xml.
++	goto end
++)
++
++if "%1" == "pseudoxml" (
++	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
++	if errorlevel 1 exit /b 1
++	echo.
++	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
++	goto end
++)
++
++:end
+--- mozjs-24.2.0/js/src/python/psutil/docs/Makefile	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/Makefile	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,177 @@
++# Makefile for Sphinx documentation
++#
++
++# You can set these variables from the command line.
++SPHINXOPTS    =
++SPHINXBUILD   = sphinx-build
++PAPER         =
++BUILDDIR      = _build
++
++# User-friendly check for sphinx-build
++ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
++$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
++endif
++
++# Internal variables.
++PAPEROPT_a4     = -D latex_paper_size=a4
++PAPEROPT_letter = -D latex_paper_size=letter
++ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
++# the i18n builder cannot share the environment and doctrees with the others
++I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
++
++.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
++
++help:
++	@echo "Please use \`make <target>' where <target> is one of"
++	@echo "  html       to make standalone HTML files"
++	@echo "  dirhtml    to make HTML files named index.html in directories"
++	@echo "  singlehtml to make a single large HTML file"
++	@echo "  pickle     to make pickle files"
++	@echo "  json       to make JSON files"
++	@echo "  htmlhelp   to make HTML files and a HTML help project"
++	@echo "  qthelp     to make HTML files and a qthelp project"
++	@echo "  devhelp    to make HTML files and a Devhelp project"
++	@echo "  epub       to make an epub"
++	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
++	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
++	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
++	@echo "  text       to make text files"
++	@echo "  man        to make manual pages"
++	@echo "  texinfo    to make Texinfo files"
++	@echo "  info       to make Texinfo files and run them through makeinfo"
++	@echo "  gettext    to make PO message catalogs"
++	@echo "  changes    to make an overview of all changed/added/deprecated items"
++	@echo "  xml        to make Docutils-native XML files"
++	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
++	@echo "  linkcheck  to check all external links for integrity"
++	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
++
++clean:
++	rm -rf $(BUILDDIR)
++
++html:
++	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
++	@echo
++	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
++
++dirhtml:
++	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
++	@echo
++	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
++
++singlehtml:
++	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
++	@echo
++	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
++
++pickle:
++	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
++	@echo
++	@echo "Build finished; now you can process the pickle files."
++
++json:
++	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
++	@echo
++	@echo "Build finished; now you can process the JSON files."
++
++htmlhelp:
++	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
++	@echo
++	@echo "Build finished; now you can run HTML Help Workshop with the" \
++	      ".hhp project file in $(BUILDDIR)/htmlhelp."
++
++qthelp:
++	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
++	@echo
++	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
++	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
++	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/psutil.qhcp"
++	@echo "To view the help file:"
++	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/psutil.qhc"
++
++devhelp:
++	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
++	@echo
++	@echo "Build finished."
++	@echo "To view the help file:"
++	@echo "# mkdir -p $$HOME/.local/share/devhelp/psutil"
++	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/psutil"
++	@echo "# devhelp"
++
++epub:
++	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
++	@echo
++	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
++
++latex:
++	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
++	@echo
++	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
++	@echo "Run \`make' in that directory to run these through (pdf)latex" \
++	      "(use \`make latexpdf' here to do that automatically)."
++
++latexpdf:
++	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
++	@echo "Running LaTeX files through pdflatex..."
++	$(MAKE) -C $(BUILDDIR)/latex all-pdf
++	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
++
++latexpdfja:
++	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
++	@echo "Running LaTeX files through platex and dvipdfmx..."
++	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
++	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
++
++text:
++	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
++	@echo
++	@echo "Build finished. The text files are in $(BUILDDIR)/text."
++
++man:
++	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
++	@echo
++	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
++
++texinfo:
++	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
++	@echo
++	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
++	@echo "Run \`make' in that directory to run these through makeinfo" \
++	      "(use \`make info' here to do that automatically)."
++
++info:
++	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
++	@echo "Running Texinfo files through makeinfo..."
++	make -C $(BUILDDIR)/texinfo info
++	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
++
++gettext:
++	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
++	@echo
++	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
++
++changes:
++	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
++	@echo
++	@echo "The overview file is in $(BUILDDIR)/changes."
++
++linkcheck:
++	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
++	@echo
++	@echo "Link check complete; look for any errors in the above output " \
++	      "or in $(BUILDDIR)/linkcheck/output.txt."
++
++doctest:
++	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
++	@echo "Testing of doctests in the sources finished, look at the " \
++	      "results in $(BUILDDIR)/doctest/output.txt."
++
++xml:
++	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
++	@echo
++	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
++
++pseudoxml:
++	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
++	@echo
++	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+--- mozjs-24.2.0/js/src/python/psutil/docs/README	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/docs/README	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,15 @@
++About
++=====
++
++This directory contains the reStructuredText (reST) sources to the psutil
++documentation.  You don't need to build them yourself, prebuilt versions are
++available at https://pythonhosted.org/psutil/.
++In case you want, you need to install sphinx first:
++
++    $ pip install sphinx
++
++Then run:
++
++    $ make html
++
++You'll then have an HTML version of the doc at _build/html/index.html.
+\ No newline at end of file
+--- mozjs-24.2.0/js/src/python/psutil/examples/disk_usage.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/disk_usage.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,16 +1,24 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ List all mounted disk partitions a-la "df -h" command.
++
++$ python examples/disk_usage.py
++Device               Total     Used     Free  Use %      Type  Mount
++/dev/sdb3            18.9G    14.7G     3.3G    77%      ext4  /
++/dev/sda6           345.9G    83.8G   244.5G    24%      ext4  /home
++/dev/sda1           296.0M    43.1M   252.9M    14%      vfat  /boot/efi
++/dev/sda2           600.0M   312.4M   287.6M    52%   fuseblk  /media/Recovery
+ """
+ 
+ import sys
++import os
+ import psutil
+-from psutil._compat import print_
++
+ 
+ def bytes2human(n):
+     # http://code.activestate.com/recipes/578019
+@@ -21,7 +29,7 @@
+     symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+     prefix = {}
+     for i, s in enumerate(symbols):
+-        prefix[s] = 1 << (i+1)*10
++        prefix[s] = 1 << (i + 1) * 10
+     for s in reversed(symbols):
+         if n >= prefix[s]:
+             value = float(n) / prefix[s]
+@@ -31,16 +39,24 @@
+ 
+ def main():
+     templ = "%-17s %8s %8s %8s %5s%% %9s  %s"
+-    print_(templ % ("Device", "Total", "Used", "Free", "Use ", "Type", "Mount"))
++    print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type",
++                   "Mount"))
+     for part in psutil.disk_partitions(all=False):
++        if os.name == 'nt':
++            if 'cdrom' in part.opts or part.fstype == '':
++                # skip cd-rom drives with no disk in it; they may raise
++                # ENOENT, pop-up a Windows GUI error for a non-ready
++                # partition or just hang.
++                continue
+         usage = psutil.disk_usage(part.mountpoint)
+-        print_(templ % (part.device,
+-                        bytes2human(usage.total),
+-                        bytes2human(usage.used),
+-                        bytes2human(usage.free),
+-                        int(usage.percent),
+-                        part.fstype,
+-                        part.mountpoint))
++        print(templ % (
++            part.device,
++            bytes2human(usage.total),
++            bytes2human(usage.used),
++            bytes2human(usage.free),
++            int(usage.percent),
++            part.fstype,
++            part.mountpoint))
+ 
+ if __name__ == '__main__':
+     sys.exit(main())
+--- mozjs-24.2.0/js/src/python/psutil/examples/free.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/free.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,31 +1,41 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ A clone of 'free' cmdline utility.
++
++$ python examples/free.py
++             total       used       free     shared    buffers      cache
++Mem:      10125520    8625996    1499524          0     349500    3307836
++Swap:            0          0          0
+ """
+ 
+ import psutil
+-from psutil._compat import print_
++
+ 
+ def main():
+     virt = psutil.virtual_memory()
+     swap = psutil.swap_memory()
+     templ = "%-7s %10s %10s %10s %10s %10s %10s"
+-    print_(templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache'))
+-    print_(templ % ('Mem:', int(virt.total / 1024),
+-                            int(virt.used / 1024),
+-                            int(virt.free / 1024),
+-                            int(getattr(virt, 'shared', 0) / 1024),
+-                            int(getattr(virt, 'buffers', 0) / 1024),
+-                            int(getattr(virt, 'cached', 0) / 1024)))
+-    print_(templ % ('Swap:', int(swap.total / 1024),
+-                             int(swap.used / 1024),
+-                             int(swap.free / 1024),
+-                             '', '', ''))
++    print(templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache'))
++    print(templ % (
++        'Mem:',
++        int(virt.total / 1024),
++        int(virt.used / 1024),
++        int(virt.free / 1024),
++        int(getattr(virt, 'shared', 0) / 1024),
++        int(getattr(virt, 'buffers', 0) / 1024),
++        int(getattr(virt, 'cached', 0) / 1024)))
++    print(templ % (
++        'Swap:', int(swap.total / 1024),
++        int(swap.used / 1024),
++        int(swap.free / 1024),
++        '',
++        '',
++        ''))
+ 
+ if __name__ == '__main__':
+     main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/ifconfig.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/examples/ifconfig.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,78 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""
++A clone of 'ifconfig' on UNIX.
++
++$ python examples/ifconfig.py
++lo (speed=0MB, duplex=?, mtu=65536, up=yes):
++    IPv4     address   : 127.0.0.1
++             broadcast : 127.0.0.1
++             netmask   : 255.0.0.0
++    IPv6     address   : ::1
++             netmask   : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
++    MAC      address   : 00:00:00:00:00:00
++             broadcast : 00:00:00:00:00:00
++
++wlan0 (speed=0MB, duplex=?, mtu=1500, up=yes):
++    IPv4     address   : 10.0.3.1
++             broadcast : 10.0.3.255
++             netmask   : 255.255.255.0
++    IPv6     address   : fe80::3005:adff:fe31:8698
++             netmask   : ffff:ffff:ffff:ffff::
++    MAC      address   : 32:05:ad:31:86:98
++             broadcast : ff:ff:ff:ff:ff:ff
++
++eth0 (speed=100MB, duplex=full, mtu=1500, up=yes):
++    IPv4     address   : 192.168.1.2
++             broadcast : 192.168.1.255
++             netmask   : 255.255.255.0
++    IPv6     address   : fe80::c685:8ff:fe45:641
++             netmask   : ffff:ffff:ffff:ffff::
++    MAC      address   : c4:85:08:45:06:41
++             broadcast : ff:ff:ff:ff:ff:ff
++"""
++
++from __future__ import print_function
++import socket
++
++import psutil
++
++
++af_map = {
++    socket.AF_INET: 'IPv4',
++    socket.AF_INET6: 'IPv6',
++    psutil.AF_LINK: 'MAC',
++}
++
++duplex_map = {
++    psutil.NIC_DUPLEX_FULL: "full",
++    psutil.NIC_DUPLEX_HALF: "half",
++    psutil.NIC_DUPLEX_UNKNOWN: "?",
++}
++
++
++def main():
++    stats = psutil.net_if_stats()
++    for nic, addrs in psutil.net_if_addrs().items():
++        if nic in stats:
++            print("%s (speed=%sMB, duplex=%s, mtu=%s, up=%s):" % (
++                nic, stats[nic].speed, duplex_map[stats[nic].duplex],
++                stats[nic].mtu, "yes" if stats[nic].isup else "no"))
++        else:
++            print("%s:" % (nic))
++        for addr in addrs:
++            print("    %-8s" % af_map.get(addr.family, addr.family), end="")
++            print(" address   : %s" % addr.address)
++            if addr.broadcast:
++                print("             broadcast : %s" % addr.broadcast)
++            if addr.netmask:
++                print("             netmask   : %s" % addr.netmask)
++        print("")
++
++
++if __name__ == '__main__':
++    main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/iotop.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/iotop.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,6 +1,6 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -12,17 +12,33 @@
+ counters).
+ It doesn't work on Windows as curses module is required.
+ 
++Example output:
++
++$ python examples/iotop.py
++Total DISK READ: 0.00 B/s | Total DISK WRITE: 472.00 K/s
++PID   USER      DISK READ  DISK WRITE  COMMAND
++13155 giampao    0.00 B/s  428.00 K/s  /usr/bin/google-chrome-beta
++3260  giampao    0.00 B/s    0.00 B/s  bash
++3779  giampao    0.00 B/s    0.00 B/s  gnome-session --session=ubuntu
++3830  giampao    0.00 B/s    0.00 B/s  /usr/bin/dbus-launch
++3831  giampao    0.00 B/s    0.00 B/s  //bin/dbus-daemon --fork --print-pid 5
++3841  giampao    0.00 B/s    0.00 B/s  /usr/lib/at-spi-bus-launcher
++3845  giampao    0.00 B/s    0.00 B/s  /bin/dbus-daemon
++3848  giampao    0.00 B/s    0.00 B/s  /usr/lib/at-spi2-core/at-spi2-registryd
++3862  giampao    0.00 B/s    0.00 B/s  /usr/lib/gnome-settings-daemon
++
+ Author: Giampaolo Rodola' <[email protected]>
+ """
+ 
+-import os
++import atexit
++import time
+ import sys
+-import psutil
+-if not hasattr(psutil.Process, 'get_io_counters') or os.name != 'posix':
++try:
++    import curses
++except ImportError:
+     sys.exit('platform not supported')
+-import time
+-import curses
+-import atexit
++
++import psutil
+ 
+ 
+ # --- curses stuff
+@@ -37,6 +53,7 @@
+ curses.endwin()
+ lineno = 0
+ 
++
+ def print_line(line, highlight=False):
+     """A thin wrapper around curses's addstr()."""
+     global lineno
+@@ -65,13 +82,14 @@
+     symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+     prefix = {}
+     for i, s in enumerate(symbols):
+-        prefix[s] = 1 << (i+1)*10
++        prefix[s] = 1 << (i + 1) * 10
+     for s in reversed(symbols):
+         if n >= prefix[s]:
+             value = float(n) / prefix[s]
+             return '%.2f %s/s' % (value, s)
+     return '%.2f B/s' % (n)
+ 
++
+ def poll(interval):
+     """Calculate IO usage by comparing IO statics before and
+     after the interval.
+@@ -82,7 +100,7 @@
+     procs = [p for p in psutil.process_iter()]
+     for p in procs[:]:
+         try:
+-            p._before = p.get_io_counters()
++            p._before = p.io_counters()
+         except psutil.Error:
+             procs.remove(p)
+             continue
+@@ -94,12 +112,12 @@
+     # then retrieve the same info again
+     for p in procs[:]:
+         try:
+-            p._after = p.get_io_counters()
+-            p._cmdline = ' '.join(p.cmdline)
++            p._after = p.io_counters()
++            p._cmdline = ' '.join(p.cmdline())
+             if not p._cmdline:
+-                p._cmdline = p.name
+-            p._username = p.username
+-        except psutil.NoSuchProcess:
++                p._cmdline = p.name()
++            p._username = p.username()
++        except (psutil.NoSuchProcess, psutil.ZombieProcess):
+             procs.remove(p)
+     disks_after = psutil.disk_io_counters()
+ 
+@@ -134,21 +152,23 @@
+     print_line(header, highlight=True)
+ 
+     for p in procs:
+-        line = templ % (p.pid,
+-                        p._username[:7],
+-                        bytes2human(p._read_per_sec),
+-                        bytes2human(p._write_per_sec),
+-                        p._cmdline)
++        line = templ % (
++            p.pid,
++            p._username[:7],
++            bytes2human(p._read_per_sec),
++            bytes2human(p._write_per_sec),
++            p._cmdline)
+         try:
+             print_line(line)
+         except curses.error:
+             break
+     win.refresh()
+ 
++
+ def main():
+     try:
+         interval = 0
+-        while 1:
++        while True:
+             args = poll(interval)
+             refresh_window(*args)
+             interval = 1
+--- mozjs-24.2.0/js/src/python/psutil/examples/killall.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/killall.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,6 +1,6 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -12,6 +12,7 @@
+ import sys
+ import psutil
+ 
++
+ def main():
+     if len(sys.argv) != 2:
+         sys.exit('usage: %s name' % __file__)
+@@ -20,7 +21,7 @@
+ 
+     killed = []
+     for proc in psutil.process_iter():
+-        if proc.name == NAME and proc.pid != os.getpid():
++        if proc.name() == NAME and proc.pid != os.getpid():
+             proc.kill()
+             killed.append(proc.pid)
+     if not killed:
+--- mozjs-24.2.0/js/src/python/psutil/examples/meminfo.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/meminfo.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,30 +1,67 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ Print system memory information.
++
++$ python examples/meminfo.py
++MEMORY
++------
++Total      :    9.7G
++Available  :    4.9G
++Percent    :    49.0
++Used       :    8.2G
++Free       :    1.4G
++Active     :    5.6G
++Inactive   :    2.1G
++Buffers    :  341.2M
++Cached     :    3.2G
++
++SWAP
++----
++Total      :      0B
++Used       :      0B
++Free       :      0B
++Percent    :     0.0
++Sin        :      0B
++Sout       :      0B
+ """
+ 
+ import psutil
+-from psutil._compat import print_
+ 
+-def to_meg(n):
+-    return str(int(n / 1024 / 1024)) + "M"
++
++def bytes2human(n):
++    # http://code.activestate.com/recipes/578019
++    # >>> bytes2human(10000)
++    # '9.8K'
++    # >>> bytes2human(100001221)
++    # '95.4M'
++    symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
++    prefix = {}
++    for i, s in enumerate(symbols):
++        prefix[s] = 1 << (i + 1) * 10
++    for s in reversed(symbols):
++        if n >= prefix[s]:
++            value = float(n) / prefix[s]
++            return '%.1f%s' % (value, s)
++    return "%sB" % n
++
+ 
+ def pprint_ntuple(nt):
+     for name in nt._fields:
+         value = getattr(nt, name)
+         if name != 'percent':
+-            value = to_meg(value)
+-        print_('%-10s : %7s' % (name.capitalize(), value))
++            value = bytes2human(value)
++        print('%-10s : %7s' % (name.capitalize(), value))
++
+ 
+ def main():
+-    print_('MEMORY\n------')
++    print('MEMORY\n------')
+     pprint_ntuple(psutil.virtual_memory())
+-    print_('\nSWAP\n----')
++    print('\nSWAP\n----')
+     pprint_ntuple(psutil.swap_memory())
+ 
+ if __name__ == '__main__':
+--- mozjs-24.2.0/js/src/python/psutil/examples/netstat.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/netstat.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,50 +1,64 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+-A clone of 'netstat'.
++A clone of 'netstat -antp' on Linux.
++
++$ python examples/netstat.py
++Proto Local address      Remote address   Status        PID    Program name
++tcp   127.0.0.1:48256    127.0.0.1:45884  ESTABLISHED   13646  chrome
++tcp   127.0.0.1:47073    127.0.0.1:45884  ESTABLISHED   13646  chrome
++tcp   127.0.0.1:47072    127.0.0.1:45884  ESTABLISHED   13646  chrome
++tcp   127.0.0.1:45884    -                LISTEN        13651  GoogleTalkPlugi
++tcp   127.0.0.1:60948    -                LISTEN        13651  GoogleTalkPlugi
++tcp   172.17.42.1:49102  127.0.0.1:19305  CLOSE_WAIT    13651  GoogleTalkPlugi
++tcp   172.17.42.1:55797  127.0.0.1:443    CLOSE_WAIT    13651  GoogleTalkPlugi
++...
+ """
+ 
+ import socket
+ from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
+ 
+ import psutil
+-from psutil._compat import print_
+ 
+ 
+ AD = "-"
+ AF_INET6 = getattr(socket, 'AF_INET6', object())
+-proto_map = {(AF_INET, SOCK_STREAM)  : 'tcp',
+-             (AF_INET6, SOCK_STREAM) : 'tcp6',
+-             (AF_INET, SOCK_DGRAM)   : 'udp',
+-             (AF_INET6, SOCK_DGRAM)  : 'udp6'}
++proto_map = {
++    (AF_INET, SOCK_STREAM): 'tcp',
++    (AF_INET6, SOCK_STREAM): 'tcp6',
++    (AF_INET, SOCK_DGRAM): 'udp',
++    (AF_INET6, SOCK_DGRAM): 'udp6',
++}
++
+ 
+ def main():
+-    templ = "%-5s %-22s %-22s %-13s %-6s %s"
+-    print_(templ % ("Proto", "Local addr", "Remote addr", "Status", "PID",
+-                    "Program name"))
++    templ = "%-5s %-30s %-30s %-13s %-6s %s"
++    print(templ % (
++        "Proto", "Local address", "Remote address", "Status", "PID",
++        "Program name"))
++    proc_names = {}
+     for p in psutil.process_iter():
+-        name = '?'
+         try:
+-            name = p.name
+-            cons = p.get_connections(kind='inet')
+-        except psutil.AccessDenied:
+-            print_(templ % (AD, AD, AD, AD, p.pid, name))
+-        else:
+-            for c in cons:
+-                raddr = ""
+-                laddr = "%s:%s" % (c.local_address)
+-                if c.remote_address:
+-                    raddr = "%s:%s" % (c.remote_address)
+-                print_(templ % (proto_map[(c.family, c.type)],
+-                                laddr,
+-                                raddr,
+-                                str(c.status),
+-                                p.pid,
+-                                name[:15]))
++            proc_names[p.pid] = p.name()
++        except psutil.Error:
++            pass
++    for c in psutil.net_connections(kind='inet'):
++        laddr = "%s:%s" % (c.laddr)
++        raddr = ""
++        if c.raddr:
++            raddr = "%s:%s" % (c.raddr)
++        print(templ % (
++            proto_map[(c.family, c.type)],
++            laddr,
++            raddr or AD,
++            c.status,
++            c.pid or AD,
++            proc_names.get(c.pid, '?')[:15],
++        ))
+ 
+ if __name__ == '__main__':
+     main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/nettop.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/nettop.py	2015-06-17 19:33:33.000000000 -0700
+@@ -2,7 +2,7 @@
+ #
+ # $Id: iotop.py 1160 2011-10-14 18:50:36Z [email protected] $
+ #
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -10,15 +10,34 @@
+ Shows real-time network statistics.
+ 
+ Author: Giampaolo Rodola' <[email protected]>
++
++$ python examples/nettop.py
++-----------------------------------------------------------
++total bytes:           sent: 1.49 G       received: 4.82 G
++total packets:         sent: 7338724      received: 8082712
++
++wlan0                     TOTAL         PER-SEC
++-----------------------------------------------------------
++bytes-sent               1.29 G        0.00 B/s
++bytes-recv               3.48 G        0.00 B/s
++pkts-sent               7221782               0
++pkts-recv               6753724               0
++
++eth1                      TOTAL         PER-SEC
++-----------------------------------------------------------
++bytes-sent             131.77 M        0.00 B/s
++bytes-recv               1.28 G        0.00 B/s
++pkts-sent                     0               0
++pkts-recv               1214470               0
+ """
+ 
+-import sys
+-import os
+-if os.name != 'posix':
+-    sys.exit('platform not supported')
+-import curses
+ import atexit
+ import time
++import sys
++try:
++    import curses
++except ImportError:
++    sys.exit('platform not supported')
+ 
+ import psutil
+ 
+@@ -35,6 +54,7 @@
+ curses.endwin()
+ lineno = 0
+ 
++
+ def print_line(line, highlight=False):
+     """A thin wrapper around curses's addstr()."""
+     global lineno
+@@ -63,21 +83,22 @@
+     symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+     prefix = {}
+     for i, s in enumerate(symbols):
+-        prefix[s] = 1 << (i+1)*10
++        prefix[s] = 1 << (i + 1) * 10
+     for s in reversed(symbols):
+         if n >= prefix[s]:
+             value = float(n) / prefix[s]
+             return '%.2f %s' % (value, s)
+     return '%.2f B' % (n)
+ 
++
+ def poll(interval):
+     """Retrieve raw stats within an interval window."""
+-    tot_before = psutil.network_io_counters()
+-    pnic_before = psutil.network_io_counters(pernic=True)
++    tot_before = psutil.net_io_counters()
++    pnic_before = psutil.net_io_counters(pernic=True)
+     # sleep some time
+     time.sleep(interval)
+-    tot_after = psutil.network_io_counters()
+-    pnic_after = psutil.network_io_counters(pernic=True)
++    tot_after = psutil.net_io_counters()
++    pnic_after = psutil.net_io_counters(pernic=True)
+     return (tot_before, tot_after, pnic_before, pnic_after)
+ 
+ 
+@@ -86,14 +107,12 @@
+     global lineno
+ 
+     # totals
+-    print_line("total bytes:           sent: %-10s   received: %s" \
+-          % (bytes2human(tot_after.bytes_sent),
+-             bytes2human(tot_after.bytes_recv))
++    print_line("total bytes:           sent: %-10s   received: %s" % (
++        bytes2human(tot_after.bytes_sent),
++        bytes2human(tot_after.bytes_recv))
+     )
+-    print_line("total packets:         sent: %-10s   received: %s" \
+-          % (tot_after.packets_sent, tot_after.packets_recv)
+-    )
+-
++    print_line("total packets:         sent: %-10s   received: %s" % (
++        tot_after.packets_sent, tot_after.packets_recv))
+ 
+     # per-network interface details: let's sort network interfaces so
+     # that the ones which generated more traffic are shown first
+@@ -108,12 +127,14 @@
+         print_line(templ % (
+             "bytes-sent",
+             bytes2human(stats_after.bytes_sent),
+-            bytes2human(stats_after.bytes_sent - stats_before.bytes_sent) + '/s',
++            bytes2human(
++                stats_after.bytes_sent - stats_before.bytes_sent) + '/s',
+         ))
+         print_line(templ % (
+             "bytes-recv",
+             bytes2human(stats_after.bytes_recv),
+-            bytes2human(stats_after.bytes_recv - stats_before.bytes_recv) + '/s',
++            bytes2human(
++                stats_after.bytes_recv - stats_before.bytes_recv) + '/s',
+         ))
+         print_line(templ % (
+             "pkts-sent",
+@@ -133,7 +154,7 @@
+ def main():
+     try:
+         interval = 0
+-        while 1:
++        while True:
+             args = poll(interval)
+             refresh_window(*args)
+             interval = 1
+--- mozjs-24.2.0/js/src/python/psutil/examples/pidof.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/examples/pidof.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,53 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola', karthikrev. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++
++"""
++A clone of 'pidof' cmdline utility.
++$ pidof python
++1140 1138 1136 1134 1133 1129 1127 1125 1121 1120 1119
++"""
++
++from __future__ import print_function
++import psutil
++import sys
++
++
++def pidof(pgname):
++    pids = []
++    for proc in psutil.process_iter():
++        # search for matches in the process name and cmdline
++        try:
++            name = proc.name()
++        except psutil.Error:
++            pass
++        else:
++            if name == pgname:
++                pids.append(str(proc.pid))
++                continue
++
++        try:
++            cmdline = proc.cmdline()
++        except psutil.Error:
++            pass
++        else:
++            if cmdline and cmdline[0] == pgname:
++                pids.append(str(proc.pid))
++
++    return pids
++
++
++def main():
++    if len(sys.argv) != 2:
++        sys.exit('usage: %s pgname' % __file__)
++    else:
++        pgname = sys.argv[1]
++    pids = pidof(pgname)
++    if pids:
++        print(" ".join(pids))
++
++if __name__ == '__main__':
++    main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/pmap.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/pmap.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,35 +1,57 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ A clone of 'pmap' utility on Linux, 'vmmap' on OSX and 'procstat -v' on BSD.
+ Report memory map of a process.
++
++$ python examples/pmap.py 32402
++pid=32402, name=hg
++Address                 RSS  Mode    Mapping
++0000000000400000      1200K  r-xp    /usr/bin/python2.7
++0000000000838000         4K  r--p    /usr/bin/python2.7
++0000000000839000       304K  rw-p    /usr/bin/python2.7
++00000000008ae000        68K  rw-p    [anon]
++000000000275e000      5396K  rw-p    [heap]
++00002b29bb1e0000       124K  r-xp    /lib/x86_64-linux-gnu/ld-2.17.so
++00002b29bb203000         8K  rw-p    [anon]
++00002b29bb220000       528K  rw-p    [anon]
++00002b29bb2d8000       768K  rw-p    [anon]
++00002b29bb402000         4K  r--p    /lib/x86_64-linux-gnu/ld-2.17.so
++00002b29bb403000         8K  rw-p    /lib/x86_64-linux-gnu/ld-2.17.so
++00002b29bb405000        60K  r-xp    /lib/x86_64-linux-gnu/libpthread-2.17.so
++00002b29bb41d000         0K  ---p    /lib/x86_64-linux-gnu/libpthread-2.17.so
++00007fff94be6000        48K  rw-p    [stack]
++00007fff94dd1000         4K  r-xp    [vdso]
++ffffffffff600000         0K  r-xp    [vsyscall]
++...
+ """
+ 
+ import sys
+ 
+ import psutil
+-from psutil._compat import print_
++
+ 
+ def main():
+     if len(sys.argv) != 2:
+-        sys.exit('usage: pmap pid')
++        sys.exit('usage: pmap <pid>')
+     p = psutil.Process(int(sys.argv[1]))
+-    print_("pid=%s, name=%s" % (p.pid, p.name))
++    print("pid=%s, name=%s" % (p.pid, p.name()))
+     templ = "%-16s %10s  %-7s %s"
+-    print_(templ % ("Address", "RSS", "Mode", "Mapping"))
++    print(templ % ("Address", "RSS", "Mode", "Mapping"))
+     total_rss = 0
+-    for m in p.get_memory_maps(grouped=False):
++    for m in p.memory_maps(grouped=False):
+         total_rss += m.rss
+-        print_(templ % (m.addr.split('-')[0].zfill(16),
+-                        str(m.rss / 1024) + 'K' ,
+-                        m.perms,
+-                        m.path))
+-    print_("-" * 33)
+-    print_(templ % ("Total", str(total_rss / 1024) + 'K', '', ''))
++        print(templ % (
++            m.addr.split('-')[0].zfill(16),
++            str(m.rss / 1024) + 'K',
++            m.perms,
++            m.path))
++    print("-" * 33)
++    print(templ % ("Total", str(total_rss / 1024) + 'K', '', ''))
+ 
+ if __name__ == '__main__':
+     main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/process_detail.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/process_detail.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,66 +1,98 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ Print detailed information about a process.
+-
+ Author: Giampaolo Rodola' <[email protected]>
++
++$ python examples/process_detail.py
++pid               820
++name              python
++exe               /usr/bin/python2.7
++parent            29613 (bash)
++cmdline           python examples/process_detail.py
++started           2014-41-27 03:41
++user              giampaolo
++uids              real=1000, effective=1000, saved=1000
++gids              real=1000, effective=1000, saved=1000
++terminal          /dev/pts/17
++cwd               /ssd/svn/psutil
++memory            0.1% (resident=10.6M, virtual=58.5M)
++cpu               0.0% (user=0.09, system=0.0)
++status            running
++niceness          0
++num threads       1
++I/O               bytes-read=0B, bytes-written=0B
++open files
++running threads   id=820, user-time=0.09, sys-time=0.0
+ """
+ 
+-import os
+ import datetime
++import os
+ import socket
+ import sys
+ 
+ import psutil
+ 
+ 
++POSIX = os.name == 'posix'
++
++
+ def convert_bytes(n):
+     symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+     prefix = {}
+     for i, s in enumerate(symbols):
+-        prefix[s] = 1 << (i+1)*10
++        prefix[s] = 1 << (i + 1) * 10
+     for s in reversed(symbols):
+         if n >= prefix[s]:
+             value = float(n) / prefix[s]
+             return '%.1f%s' % (value, s)
+     return "%sB" % n
+ 
++
+ def print_(a, b):
+-    if sys.stdout.isatty() and os.name == 'posix':
+-        fmt = '\x1b[1;32m%-17s\x1b[0m %s' %(a, b)
++    if sys.stdout.isatty() and POSIX:
++        fmt = '\x1b[1;32m%-17s\x1b[0m %s' % (a, b)
+     else:
+-        fmt = '%-15s %s' %(a, b)
++        fmt = '%-15s %s' % (a, b)
+     # python 2/3 compatibility layer
+     sys.stdout.write(fmt + '\n')
+     sys.stdout.flush()
+ 
++
+ def run(pid):
+     ACCESS_DENIED = ''
+     try:
+         p = psutil.Process(pid)
+         pinfo = p.as_dict(ad_value=ACCESS_DENIED)
+-    except psutil.NoSuchProcess:
+-        sys.exit(str(sys.exc_info()[1]))
++    except psutil.NoSuchProcess as err:
++        sys.exit(str(err))
+ 
+     try:
+-        if p.parent:
+-            parent = '(%s)' % p.parent.name
++        parent = p.parent()
++        if parent:
++            parent = '(%s)' % parent.name()
+         else:
+             parent = ''
+     except psutil.Error:
+         parent = ''
+-    started = datetime.datetime.fromtimestamp(pinfo['create_time']
+-                                                ).strftime('%Y-%M-%d %H:%M')
+-    io = pinfo.get('io_counters', None)
+-    mem = '%s%% (resident=%s, virtual=%s) ' % (
+-                                      round(pinfo['memory_percent'], 1),
+-                                      convert_bytes(pinfo['memory_info'].rss),
+-                                      convert_bytes(pinfo['memory_info'].vms))
+-    children = p.get_children()
++    if pinfo['create_time'] != ACCESS_DENIED:
++        started = datetime.datetime.fromtimestamp(
++            pinfo['create_time']).strftime('%Y-%m-%d %H:%M')
++    else:
++        started = ACCESS_DENIED
++    io = pinfo.get('io_counters', ACCESS_DENIED)
++    if pinfo['memory_info'] != ACCESS_DENIED:
++        mem = '%s%% (resident=%s, virtual=%s) ' % (
++            round(pinfo['memory_percent'], 1),
++            convert_bytes(pinfo['memory_info'].rss),
++            convert_bytes(pinfo['memory_info'].vms))
++    else:
++        mem = ACCESS_DENIED
++    children = p.children()
+ 
+     print_('pid', pinfo['pid'])
+     print_('name', pinfo['name'])
+@@ -69,39 +101,41 @@
+     print_('cmdline', ' '.join(pinfo['cmdline']))
+     print_('started', started)
+     print_('user', pinfo['username'])
+-    if os.name == 'posix':
++    if POSIX and pinfo['uids'] and pinfo['gids']:
+         print_('uids', 'real=%s, effective=%s, saved=%s' % pinfo['uids'])
++    if POSIX and pinfo['gids']:
+         print_('gids', 'real=%s, effective=%s, saved=%s' % pinfo['gids'])
++    if POSIX:
+         print_('terminal', pinfo['terminal'] or '')
+-    if hasattr(p, 'getcwd'):
+-        print_('cwd', pinfo['cwd'])
++    print_('cwd', pinfo['cwd'])
+     print_('memory', mem)
+-    print_('cpu', '%s%% (user=%s, system=%s)' % (pinfo['cpu_percent'],
+-                                                 pinfo['cpu_times'].user,
+-                                                 pinfo['cpu_times'].system))
++    print_('cpu', '%s%% (user=%s, system=%s)' % (
++        pinfo['cpu_percent'],
++        getattr(pinfo['cpu_times'], 'user', '?'),
++        getattr(pinfo['cpu_times'], 'system', '?')))
+     print_('status', pinfo['status'])
+     print_('niceness', pinfo['nice'])
+     print_('num threads', pinfo['num_threads'])
+     if io != ACCESS_DENIED:
+-        print_('I/O', 'bytes-read=%s, bytes-written=%s' % \
+-                                               (convert_bytes(io.read_bytes),
+-                                                convert_bytes(io.write_bytes)))
++        print_('I/O', 'bytes-read=%s, bytes-written=%s' % (
++            convert_bytes(io.read_bytes),
++            convert_bytes(io.write_bytes)))
+     if children:
+         print_('children', '')
+         for child in children:
+-            print_('', 'pid=%s name=%s' % (child.pid, child.name))
++            print_('', 'pid=%s name=%s' % (child.pid, child.name()))
+ 
+     if pinfo['open_files'] != ACCESS_DENIED:
+         print_('open files', '')
+         for file in pinfo['open_files']:
+-            print_('',  'fd=%s %s ' % (file.fd, file.path))
++            print_('', 'fd=%s %s ' % (file.fd, file.path))
+ 
+     if pinfo['threads']:
+         print_('running threads', '')
+         for thread in pinfo['threads']:
+-            print_('',  'id=%s, user-time=%s, sys-time=%s' \
+-                         % (thread.id, thread.user_time, thread.system_time))
+-    if pinfo['connections'] != ACCESS_DENIED:
++            print_('', 'id=%s, user-time=%s, sys-time=%s' % (
++                thread.id, thread.user_time, thread.system_time))
++    if pinfo['connections'] not in (ACCESS_DENIED, []):
+         print_('open connections', '')
+         for conn in pinfo['connections']:
+             if conn.type == socket.SOCK_STREAM:
+@@ -110,13 +144,14 @@
+                 type = 'UDP'
+             else:
+                 type = 'UNIX'
+-            lip, lport = conn.local_address
+-            if not conn.remote_address:
++            lip, lport = conn.laddr
++            if not conn.raddr:
+                 rip, rport = '*', '*'
+             else:
+-                rip, rport = conn.remote_address
+-            print_('',  '%s:%s -> %s:%s type=%s status=%s' \
+-                         % (lip, lport, rip, rport, type, conn.status))
++                rip, rport = conn.raddr
++            print_('', '%s:%s -> %s:%s type=%s status=%s' % (
++                lip, lport, rip, rport, type, conn.status))
++
+ 
+ def main(argv=None):
+     if argv is None:
+--- mozjs-24.2.0/js/src/python/psutil/examples/ps.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/examples/ps.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,81 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""
++A clone of 'ps -aux' on UNIX.
++
++$ python examples/ps.py
++...
++"""
++
++import datetime
++import os
++import time
++
++import psutil
++
++
++def main():
++    today_day = datetime.date.today()
++    templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s  %s"
++    attrs = ['pid', 'cpu_percent', 'memory_percent', 'name', 'cpu_times',
++             'create_time', 'memory_info']
++    if os.name == 'posix':
++        attrs.append('uids')
++        attrs.append('terminal')
++    print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
++                   "START", "TIME", "COMMAND"))
++    for p in psutil.process_iter():
++        try:
++            pinfo = p.as_dict(attrs, ad_value='')
++        except psutil.NoSuchProcess:
++            pass
++        else:
++            if pinfo['create_time']:
++                ctime = datetime.datetime.fromtimestamp(pinfo['create_time'])
++                if ctime.date() == today_day:
++                    ctime = ctime.strftime("%H:%M")
++                else:
++                    ctime = ctime.strftime("%b%d")
++            else:
++                ctime = ''
++            cputime = time.strftime("%M:%S",
++                                    time.localtime(sum(pinfo['cpu_times'])))
++            try:
++                user = p.username()
++            except KeyError:
++                if os.name == 'posix':
++                    if pinfo['uids']:
++                        user = str(pinfo['uids'].real)
++                    else:
++                        user = ''
++                else:
++                    raise
++            except psutil.Error:
++                user = ''
++            if os.name == 'nt' and '\\' in user:
++                user = user.split('\\')[1]
++            vms = pinfo['memory_info'] and \
++                int(pinfo['memory_info'].vms / 1024) or '?'
++            rss = pinfo['memory_info'] and \
++                int(pinfo['memory_info'].rss / 1024) or '?'
++            memp = pinfo['memory_percent'] and \
++                round(pinfo['memory_percent'], 1) or '?'
++            print(templ % (
++                user[:10],
++                pinfo['pid'],
++                pinfo['cpu_percent'],
++                memp,
++                vms,
++                rss,
++                pinfo.get('terminal', '') or '?',
++                ctime,
++                cputime,
++                pinfo['name'].strip() or '?'))
++
++
++if __name__ == '__main__':
++    main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/pstree.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/examples/pstree.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,71 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""
++Similar to 'ps aux --forest' on Linux, prints the process list
++as a tree structure.
++
++$ python examples/pstree.py
++0 ?
++|- 1 init
++| |- 289 cgmanager
++| |- 616 upstart-socket-bridge
++| |- 628 rpcbind
++| |- 892 upstart-file-bridge
++| |- 907 dbus-daemon
++| |- 978 avahi-daemon
++| | `_ 979 avahi-daemon
++| |- 987 NetworkManager
++| | |- 2242 dnsmasq
++| | `_ 10699 dhclient
++| |- 993 polkitd
++| |- 1061 getty
++| |- 1066 su
++| | `_ 1190 salt-minion...
++...
++"""
++
++from __future__ import print_function
++import collections
++import sys
++
++import psutil
++
++
++def print_tree(parent, tree, indent=''):
++    try:
++        name = psutil.Process(parent).name()
++    except psutil.Error:
++        name = "?"
++    print(parent, name)
++    if parent not in tree:
++        return
++    children = tree[parent][:-1]
++    for child in children:
++        sys.stdout.write(indent + "|- ")
++        print_tree(child, tree, indent + "| ")
++    child = tree[parent][-1]
++    sys.stdout.write(indent + "`_ ")
++    print_tree(child, tree, indent + "  ")
++
++
++def main():
++    # construct a dict where 'values' are all the processes
++    # having 'key' as their parent
++    tree = collections.defaultdict(list)
++    for p in psutil.process_iter():
++        try:
++            tree[p.ppid()].append(p.pid)
++        except (psutil.NoSuchProcess, psutil.ZombieProcess):
++            pass
++    # on systems supporting PID 0, PID 0's parent is usually 0
++    if 0 in tree and 0 in tree[0]:
++        tree[0].remove(0)
++    print_tree(min(tree), tree)
++
++
++if __name__ == '__main__':
++    main()
+--- mozjs-24.2.0/js/src/python/psutil/examples/top.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/top.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,6 +1,6 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -8,16 +8,41 @@
+ A clone of top / htop.
+ 
+ Author: Giampaolo Rodola' <[email protected]>
++
++$ python examples/top.py
++ CPU0  [|                                       ]   4.9%
++ CPU1  [|||                                     ]   7.8%
++ CPU2  [                                        ]   2.0%
++ CPU3  [|||||                                   ]  13.9%
++ Mem   [|||||||||||||||||||                     ]  49.8%  4920M/9888M
++ Swap  [                                        ]   0.0%     0M/0M
++ Processes: 287 (running=1 sleeping=286)
++ Load average: 0.34 0.54 0.46  Uptime: 3 days, 10:16:37
++
++PID    USER       NI  VIRT   RES   CPU% MEM%     TIME+  NAME
++------------------------------------------------------------
++989    giampaol    0   66M   12M    7.4  0.1   0:00.61  python
++2083   root        0  506M  159M    6.5  1.6   0:29.26  Xorg
++4503   giampaol    0  599M   25M    6.5  0.3   3:32.60  gnome-terminal
++3868   giampaol    0  358M    8M    2.8  0.1  23:12.60  pulseaudio
++3936   giampaol    0    1G  111M    2.8  1.1  33:41.67  compiz
++4401   giampaol    0  536M  141M    2.8  1.4  35:42.73  skype
++4047   giampaol    0  743M   76M    1.8  0.8  42:03.33  unity-panel-service
++13155  giampaol    0    1G  280M    1.8  2.8  41:57.34  chrome
++10     root        0    0B    0B    0.9  0.0   4:01.81  rcu_sched
++339    giampaol    0    1G  113M    0.9  1.1   8:15.73  chrome
++...
+ """
+ 
++from datetime import datetime, timedelta
++import atexit
+ import os
++import time
+ import sys
+-if os.name != 'posix':
++try:
++    import curses
++except ImportError:
+     sys.exit('platform not supported')
+-import time
+-import curses
+-import atexit
+-from datetime import datetime, timedelta
+ 
+ import psutil
+ 
+@@ -34,6 +59,7 @@
+ curses.endwin()
+ lineno = 0
+ 
++
+ def print_line(line, highlight=False):
+     """A thin wrapper around curses's addstr()."""
+     global lineno
+@@ -62,13 +88,14 @@
+     symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+     prefix = {}
+     for i, s in enumerate(symbols):
+-        prefix[s] = 1 << (i+1)*10
++        prefix[s] = 1 << (i + 1) * 10
+     for s in reversed(symbols):
+         if n >= prefix[s]:
+             value = int(float(n) / prefix[s])
+             return '%s%s' % (value, s)
+     return "%sB" % n
+ 
++
+ def poll(interval):
+     # sleep some time
+     time.sleep(interval)
+@@ -76,32 +103,35 @@
+     procs_status = {}
+     for p in psutil.process_iter():
+         try:
+-            p.dict = p.as_dict(['username', 'get_nice', 'get_memory_info',
+-                                'get_memory_percent', 'get_cpu_percent',
+-                                'get_cpu_times', 'name', 'status'])
++            p.dict = p.as_dict(['username', 'nice', 'memory_info',
++                                'memory_percent', 'cpu_percent',
++                                'cpu_times', 'name', 'status'])
+             try:
+-                procs_status[str(p.dict['status'])] += 1
++                procs_status[p.dict['status']] += 1
+             except KeyError:
+-                procs_status[str(p.dict['status'])] = 1
++                procs_status[p.dict['status']] = 1
+         except psutil.NoSuchProcess:
+             pass
+         else:
+             procs.append(p)
+ 
+     # return processes sorted by CPU percent usage
+-    processes = sorted(procs, key=lambda p: p.dict['cpu_percent'], reverse=True)
++    processes = sorted(procs, key=lambda p: p.dict['cpu_percent'],
++                       reverse=True)
+     return (processes, procs_status)
+ 
++
+ def print_header(procs_status, num_procs):
+     """Print system-related info, above the process list."""
+ 
+     def get_dashes(perc):
+-        dashes =  "|" * int((float(perc) / 10 * 4))
++        dashes = "|" * int((float(perc) / 10 * 4))
+         empty_dashes = " " * (40 - len(dashes))
+         return dashes, empty_dashes
+ 
+     # cpu usage
+-    for cpu_num, perc in enumerate(psutil.cpu_percent(interval=0, percpu=True)):
++    percs = psutil.cpu_percent(interval=0, percpu=True)
++    for cpu_num, perc in enumerate(percs):
+         dashes, empty_dashes = get_dashes(perc)
+         print_line(" CPU%-2s [%s%s] %5s%%" % (cpu_num, dashes, empty_dashes,
+                                               perc))
+@@ -135,12 +165,13 @@
+     st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
+     print_line(" Processes: %s (%s)" % (num_procs, ' '.join(st)))
+     # load average, uptime
+-    uptime = datetime.now() - datetime.fromtimestamp(psutil.BOOT_TIME)
++    uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
+     av1, av2, av3 = os.getloadavg()
+     line = " Load average: %.2f %.2f %.2f  Uptime: %s" \
+-            % (av1, av2, av3, str(uptime).split('.')[0])
++        % (av1, av2, av3, str(uptime).split('.')[0])
+     print_line(line)
+ 
++
+ def refresh_window(procs, procs_status):
+     """Print results on screen by using curses."""
+     curses.endwin()
+@@ -154,7 +185,7 @@
+     for p in procs:
+         # TIME+ column shows process CPU cumulative time and it
+         # is expressed as: "mm:ss.ms"
+-        if p.dict['cpu_times'] != None:
++        if p.dict['cpu_times'] is not None:
+             ctime = timedelta(seconds=sum(p.dict['cpu_times']))
+             ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60,
+                                   str((ctime.seconds % 60)).zfill(2),
+@@ -167,8 +198,12 @@
+             p.dict['memory_percent'] = ''
+         if p.dict['cpu_percent'] is None:
+             p.dict['cpu_percent'] = ''
++        if p.dict['username']:
++            username = p.dict['username'][:8]
++        else:
++            username = ""
+         line = templ % (p.pid,
+-                        p.dict['username'][:8],
++                        username,
+                         p.dict['nice'],
+                         bytes2human(getattr(p.dict['memory_info'], 'vms', 0)),
+                         bytes2human(getattr(p.dict['memory_info'], 'rss', 0)),
+@@ -187,7 +222,7 @@
+ def main():
+     try:
+         interval = 0
+-        while 1:
++        while True:
+             args = poll(interval)
+             refresh_window(*args)
+             interval = 1
+--- mozjs-24.2.0/js/src/python/psutil/examples/who.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/examples/who.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,30 +1,33 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+ A clone of 'who' command; print information about users who are
+ currently logged in.
++
++$ python examples/who.py
++giampaolo       tty7            2014-02-23 17:25  (:0)
++giampaolo       pts/7           2014-02-24 18:25  (:192.168.1.56)
++giampaolo       pts/8           2014-02-24 18:25  (:0)
++giampaolo       pts/9           2014-02-27 01:32  (:0)
+ """
+ 
+-import sys
+ from datetime import datetime
+ 
+ import psutil
+-from psutil._compat import print_
+ 
+ 
+ def main():
+-    users = psutil.get_users()
++    users = psutil.users()
+     for user in users:
+-        print_("%-15s %-15s %s  (%s)" % \
+-            (user.name,
+-             user.terminal or '-',
+-             datetime.fromtimestamp(user.started).strftime("%Y-%m-%d %H:%M"),
+-             user.host)
+-        )
++        print("%-15s %-15s %s  (%s)" % (
++            user.name,
++            user.terminal or '-',
++            datetime.fromtimestamp(user.started).strftime("%Y-%m-%d %H:%M"),
++            user.host))
+ 
+ if __name__ == '__main__':
+     main()
+--- mozjs-24.2.0/js/src/python/psutil/HISTORY	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/HISTORY	1969-12-31 16:00:00.000000000 -0800
+@@ -1,537 +0,0 @@
+-Bug tracker at http://code.google.com/p/psutil/issues
+-
+-0.7.1 - 2013-05-03
+-------------------
+-
+-BUG FIXES:
+-
+- * #325: [BSD] psutil.virtual_memory() can raise SystemError.
+-         (patch by Jan Beich)
+- * #370: [BSD] Process.get_connections() requires root.  (patch by John Baldwin)
+- * #372: [BSD] different process methods raise NoSuchProcess instead of
+-         AccessDenied.
+-
+-
+-0.7.0 - 2013-04-12
+-------------------
+-
+-NEW FEATURES
+-
+- * #233: code migrated to Mercurial (yay!)
+- * #246: psutil.error module is deprecated and scheduled for removal.
+- * #328: [Windows] process IO nice/priority support.
+- * #359: psutil.get_boot_time()
+- * #361: [Linux] psutil.cpu_times() now includes new 'steal', 'guest' and
+-         'guest_nice' fields available on recent Linux kernels.
+-         Also, psutil.cpu_percent() is more accurate.
+- * #362: cpu_times_percent() (per-CPU-time utilization as a percentage)
+-
+-BUG FIXES
+-
+- * #234: [Windows] disk_io_counters() fails to list certain disks.
+- * #264: [Windows] use of psutil.disk_partitions() may cause a message box to
+-         appear.
+- * #313: [Linux] psutil.virtual_memory() and psutil.swap_memory() can crash on
+-         certain exotic Linux flavors having an incomplete /proc interface.
+-         If that's the case we now set the unretrievable stats to 0 and raise a
+-         RuntimeWarning.
+- * #315: [OSX] fix some compilation warnings.
+- * #317: [Windows] cannot set process CPU affinity above 31 cores.
+- * #319: [Linux] process get_memory_maps() raises KeyError 'Anonymous' on Debian
+-         squeeze.
+- * #321: [UNIX] Process.ppid property is no longer cached as the kernel may set
+-         the ppid to 1 in case of a zombie process.
+- * #323: [OSX] disk_io_counters()'s read_time and write_time parameters were
+-         reporting microseconds not milliseconds.  (patch by Gregory Szorc)
+- * #331: Process cmdline is no longer cached after first acces as it may change.
+- * #333: [OSX] Leak of Mach ports on OS X (patch by [email protected])
+- * #337: [Linux] process methods not working because of a poor /proc
+-         implementation will raise NotImplementedError rather than RuntimeError
+-         and Process.as_dict() will not blow up.  (patch by Curtin1060)
+- * #338: [Linux] disk_io_counters() fails to find some disks.
+- * #339: [FreeBSD] get_pid_list() can allocate all the memory on system.
+- * #341: [Linux] psutil might crash on import due to error in retrieving system
+-         terminals map.
+- * #344: [FreeBSD] swap_memory() might return incorrect results due to
+-         kvm_open(3) not being called. (patch by Jean Sebastien)
+- * #338: [Linux] disk_io_counters() fails to find some disks.
+- * #351: [Windows] if psutil is compiled with mingw32 (provided installers for
+-         py2.4 and py2.5 are) disk_io_counters() will fail. (Patch by m.malycha)
+- * #353: [OSX] get_users() returns an empty list on OSX 10.8.
+- * #356: Process.parent now checks whether parent PID has been reused in which
+-         case returns None.
+- * #365: Process.set_nice() should check PID has not been reused by another
+-         process.
+- * #366: [FreeBSD] get_memory_maps(), get_num_fds(), get_open_files() and
+-         getcwd() Process methods raise RuntimeError instead of AccessDenied.
+-
+-API CHANGES
+-
+- * Process.cmdline property is no longer cached after first access.
+- * Process.ppid property is no longer cached after first access.
+- * [Linux] Process methods not working because of a poor /proc implementation
+-   will raise NotImplementedError instead of RuntimeError.
+- * psutil.error module is deprecated and scheduled for removal.
+-
+-
+-0.6.1 - 2012-08-16
+-------------------
+-
+-NEW FEATURES
+-
+- * #316: process cmdline property now makes a better job at guessing the process
+-         executable from the cmdline.
+-
+-BUG FIXES
+-
+- * #316: process exe was resolved in case it was a symlink.
+- * #318: python 2.4 compatibility was broken.
+-
+-API CHANGES
+-
+- * process exe can now return an empty string instead of raising AccessDenied.
+- * process exe is no longer resolved in case it's a symlink.
+-
+-
+-0.6.0 - 2012-08-13
+-------------------
+-
+-NEW FEATURES
+-
+- * #216: [POSIX] get_connections() UNIX sockets support.
+- * #220: [FreeBSD] get_connections() has been rewritten in C and no longer
+-         requires lsof.
+- * #222: [OSX] add support for process cwd.
+- * #261: process extended memory info.
+- * #295: [OSX] process executable path is now determined by asking the OS
+-         instead of being guessed from process cmdline.
+- * #297: [OSX] the Process methods below were always raising AccessDenied for
+-         any process except the current one. Now this is no longer true. Also
+-         they are 2.5x faster.
+-           - name
+-           - get_memory_info()
+-           - get_memory_percent()
+-           - get_cpu_times()
+-           - get_cpu_percent()
+-           - get_num_threads()
+- * #300: examples/pmap.py script.
+- * #301: process_iter() now yields processes sorted by their PIDs.
+- * #302: process number of voluntary and involuntary context switches.
+- * #303: [Windows] the Process methods below were always raising AccessDenied
+-         for any process not owned by current user. Now this is no longer true:
+-          - create_time
+-          - get_cpu_times()
+-          - get_cpu_percent()
+-          - get_memory_info()
+-          - get_memory_percent()
+-          - get_num_handles()
+-          - get_io_counters()
+- * #305: add examples/netstat.py script.
+- * #311: system memory functions has been refactorized and rewritten and now
+-         provide a more detailed and consistent representation of the system
+-         memory. New psutil.virtual_memory() function provides the following
+-         memory amounts:
+-          - total
+-          - available
+-          - percent
+-          - used
+-          - active [POSIX]
+-          - inactive [POSIX]
+-          - buffers (BSD, Linux)
+-          - cached (BSD, OSX)
+-          - wired (OSX, BSD)
+-          - shared [FreeBSD]
+-         New psutil.swap_memory() provides:
+-          - total
+-          - used
+-          - free
+-          - percent
+-          - sin (no. of bytes the system has swapped in from disk (cumulative))
+-          - sout (no. of bytes the system has swapped out from disk (cumulative))
+-         All old memory-related functions are deprecated.
+-         Also two new example scripts were added:  free.py and meminfo.py.
+- * #312: psutil.network_io_counters() namedtuple includes 4 new fields:
+-         errin, errout dropin and dropout, reflecting the number of packets
+-         dropped and with errors.
+-
+-BUGFIXES
+-
+- * #298: [OSX and BSD] memory leak in get_num_fds().
+- * #299: potential memory leak every time PyList_New(0) is used.
+- * #303: [Windows] potential heap corruption in get_num_threads() and
+-         get_status() Process methods.
+- * #305: [FreeBSD] psutil can't compile on FreeBSD 9 due to removal of utmp.h.
+- * #306: at C level, errors are not checked when invoking Py* functions which
+-         create or manipulate Python objects leading to potential memory related
+-         errors and/or segmentation faults.
+- * #307: [FreeBSD] values returned by psutil.network_io_counters() are wrong.
+- * #308: [BSD / Windows] psutil.virtmem_usage() wasn't actually returning
+-         information about swap memory usage as it was supposed to do. It does
+-         now.
+- * #309: get_open_files() might not return files which can not be accessed
+-         due to limited permissions. AccessDenied is now raised instead.
+-
+-API CHANGES
+-
+- * psutil.phymem_usage() is deprecated             (use psutil.virtual_memory())
+- * psutil.virtmem_usage() is deprecated            (use psutil.swap_memory())
+- * psutil.phymem_buffers() on Linux is deprecated  (use psutil.virtual_memory())
+- * psutil.cached_phymem() on Linux is deprecated   (use psutil.virtual_memory())
+- * [Windows and BSD] psutil.virtmem_usage() now returns information about swap
+-   memory instead of virtual memory.
+-
+-
+-0.5.1 - 2012-06-29
+-------------------
+-
+-NEW FEATURES
+-
+- * #293: [Windows] process executable path is now determined by asking the OS
+-         instead of being guessed from process cmdline.
+-
+-BUGFIXES
+-
+- * #292: [Linux] race condition in process files/threads/connections.
+- * #294: [Windows] Process CPU affinity is only able to set CPU #0.
+-
+-
+-0.5.0 - 2012-06-27
+-------------------
+-
+-NEW FEATURES
+-
+- * #195: [Windows] number of handles opened by process.
+- * #209: psutil.disk_partitions() now provides also mount options.
+- * #229: list users currently connected on the system (psutil.get_users()).
+- * #238: [Linux, Windows] process CPU affinity (get and set).
+- * #242: Process.get_children(recursive=True): return all process
+-         descendants.
+- * #245: [POSIX] Process.wait() incrementally consumes less CPU cycles.
+- * #257: [Windows] removed Windows 2000 support.
+- * #258: [Linux] Process.get_memory_info() is now 0.5x faster.
+- * #260: process's mapped memory regions. (Windows patch by wj32.64, OSX patch
+-         by Jeremy Whitlock)
+- * #262: [Windows] psutil.disk_partitions() was slow due to inspecting the
+-         floppy disk drive also when "all" argument was False.
+- * #273: psutil.get_process_list() is deprecated.
+- * #274: psutil no longer requires 2to3 at installation time in order to work
+-         with Python 3.
+- * #278: new Process.as_dict() method.
+- * #281: ppid, name, exe, cmdline and create_time properties of Process class
+-         are now cached after being accessed.
+- * #282: psutil.STATUS_* constants can now be compared by using their string
+-         representation.
+- * #283: speedup Process.is_running() by caching its return value in case the
+-         process is terminated.
+- * #284: [POSIX] per-process number of opened file descriptors.
+- * #287: psutil.process_iter() now caches Process instances between calls.
+- * #290: Process.nice property is deprecated in favor of new get_nice() and
+-         set_nice() methods.
+-
+-BUGFIXES
+-
+- * #193: psutil.Popen constructor can throw an exception if the spawned process
+-         terminates quickly.
+- * #240: [OSX] incorrect use of free() for Process.get_connections().
+- * #244: [POSIX] Process.wait() can hog CPU resources if called against a
+-         process which is not our children.
+- * #248: [Linux] psutil.network_io_counters() might return erroneous NIC names.
+- * #252: [Windows] process getcwd() erroneously raise NoSuchProcess for
+-         processes owned by another user.  It now raises AccessDenied instead.
+- * #266: [Windows] psutil.get_pid_list() only shows 1024 processes.
+-         (patch by Amoser)
+- * #267: [OSX] Process.get_connections() - an erroneous remote address was
+-         returned. (Patch by Amoser)
+- * #272: [Linux] Porcess.get_open_files() - potential race condition can lead to
+-         unexpected NoSuchProcess exception.  Also, we can get incorrect reports
+-         of not absolutized path names.
+- * #275: [Linux] Process.get_io_counters() erroneously raise NoSuchProcess on
+-         old Linux versions. Where not available it now raises
+-         NotImplementedError.
+- * #286: Process.is_running() doesn't actually check whether PID has been
+-         reused.
+- * #314: Process.get_children() can sometimes return non-children.
+-
+-API CHANGES
+-
+- * Process.nice property is deprecated in favor of new get_nice() and set_nice()
+-   methods.
+- * psutil.get_process_list() is deprecated.
+- * ppid, name, exe, cmdline and create_time properties of Process class are now
+-   cached after being accessed, meaning NoSuchProcess will no longer be raised
+-   in case the process is gone in the meantime.
+- * psutil.STATUS_* constants can now be compared by using their string
+-   representation.
+-
+-
+-0.4.1 - 2011-12-14
+-------------------
+-
+-BUGFIXES
+-
+- * #228: some example scripts were not working with python 3.
+- * #230: [Windows / OSX] memory leak in Process.get_connections().
+- * #232: [Linux] psutil.phymem_usage() can report erroneous values which are
+-         different than "free" command.
+- * #236: [Windows] memory/handle leak in Process's get_memory_info(),
+-         suspend() and resume() methods.
+-
+-
+-0.4.0 - 2011-10-29
+-------------------
+-
+-NEW FEATURES
+-
+- * #150: network I/O counters. (OSX and Windows patch by Jeremy Whitlock)
+- * #154: [FreeBSD] add support for process getcwd()
+- * #157: [Windows] provide installer for Python 3.2 64-bit.
+- * #198: Process.wait(timeout=0) can now be used to make wait() return
+-         immediately.
+- * #206: disk I/O counters. (OSX and Windows patch by Jeremy Whitlock)
+- * #213: examples/iotop.py script.
+- * #217: Process.get_connections() now has a "kind" argument to filter
+-   for connections with different criteria.
+- * #221: [FreeBSD] Process.get_open_files has been rewritten in C and no longer
+-   relies on lsof.
+- * #223: examples/top.py script.
+- * #227: examples/nettop.py script.
+-
+-BUGFIXES
+-
+- * #135: [OSX] psutil cannot create Process object.
+- * #144: [Linux] no longer support 0 special PID.
+- * #188: [Linux] psutil import error on Linux ARM architectures.
+- * #194: [POSIX] psutil.Process.get_cpu_percent() now reports a percentage over
+-         100 on multicore processors.
+- * #197: [Linux] Process.get_connections() is broken on platforms not supporting
+-         IPv6.
+- * #200: [Linux] psutil.NUM_CPUS not working on armel and sparc architectures
+-         and causing crash on module import.
+- * #201: [Linux] Process.get_connections() is broken on big-endian
+-          architectures.
+- * #211: Process instance can unexpectedly raise NoSuchProcess if tested for
+-         equality with another object.
+- * #218: [Linux] crash at import time on Debian 64-bit because of a missing line
+-         in /proc/meminfo.
+- * #226: [FreeBSD] crash at import time on FreeBSD 7 and minor.
+-
+-
+-0.3.0 - 2011-07-08
+-------------------
+-
+-NEW FEATURES
+-
+- * #125: system per-cpu percentage utilization and times.
+- * #163: per-process associated terminal (TTY).
+- * #171: added get_phymem() and get_virtmem() functions returning system
+-         memory information (total, used, free) and memory percent usage.
+-         total_* avail_* and used_* memory functions are deprecated.
+- * #172: disk usage statistics.
+- * #174: mounted disk partitions.
+- * #179: setuptools is now used in setup.py
+-
+-BUGFIXES
+-
+- * #159: SetSeDebug() does not close handles or unset impersonation on return.
+- * #164: [Windows] wait function raises a TimeoutException when a process
+-         returns -1 .
+- * #165: process.status raises an unhandled exception.
+- * #166: get_memory_info() leaks handles hogging system resources.
+- * #168: psutil.cpu_percent() returns erroneous results when used in
+-         non-blocking mode.  (patch by Philip Roberts)
+- * #178: OSX - Process.get_threads() leaks memory
+- * #180: [Windows] Process's get_num_threads() and get_threads() methods can
+-         raise NoSuchProcess exception while process still exists.
+-
+-
+-0.2.1 - 2011-03-20
+-------------------
+-
+-NEW FEATURES
+-
+- * #64: per-process I/O counters.
+- * #116: per-process wait() (wait for process to terminate and return its exit
+-         code).
+- * #134: per-process get_threads() returning information (id, user and kernel
+-         times) about threads opened by process.
+- * #136: process executable path on FreeBSD is now determined by asking the
+-         kernel instead of guessing it from cmdline[0].
+- * #137: per-process real, effective and saved user and group ids.
+- * #140: system boot time.
+- * #142: per-process get and set niceness (priority).
+- * #143: per-process status.
+- * #147: per-process I/O nice (priority) - Linux only.
+- * #148: psutil.Popen class which tidies up subprocess.Popen and psutil.Process
+-         in a unique interface.
+- * #152: [OSX] get_process_open_files() implementation has been rewritten
+-         in C and no longer relies on lsof resulting in a 3x speedup.
+- * #153: [OSX] get_process_connection() implementation has been rewritten
+-         in C and no longer relies on lsof resulting in a 3x speedup.
+-
+-BUGFIXES
+-
+- * #83:  process cmdline is empty on OSX 64-bit.
+- * #130: a race condition can cause IOError exception be raised on
+-         Linux if process disappears between open() and subsequent read() calls.
+- * #145: WindowsError was raised instead of psutil.AccessDenied when using
+-         process resume() or suspend() on Windows.
+- * #146: 'exe' property on Linux can raise TypeError if path contains NULL
+-         bytes.
+- * #151: exe and getcwd() for PID 0 on Linux return inconsistent data.
+-
+-API CHANGES
+-
+- * Process "uid" and "gid" properties are deprecated in favor of "uids" and
+-   "gids" properties.
+-
+-
+-0.2.0 - 2010-11-13
+-------------------
+-
+-NEW FEATURES
+-
+- * #79: per-process open files.
+- * #88: total system physical cached memory.
+- * #88: total system physical memory buffers used by the kernel.
+- * #91: per-process send_signal() and terminate() methods.
+- * #95: NoSuchProcess and AccessDenied exception classes now provide "pid",
+-        "name" and "msg" attributes.
+- * #97: per-process children.
+- * #98: Process.get_cpu_times() and Process.get_memory_info now return
+-        a namedtuple instead of a tuple.
+- * #103: per-process opened TCP and UDP connections.
+- * #107: add support for Windows 64 bit. (patch by cjgohlke)
+- * #111: per-process executable name.
+- * #113: exception messages now include process name and pid.
+- * #114: process username Windows implementation has been rewritten in pure
+-         C and no longer uses WMI resulting in a big speedup. Also, pywin32 is no
+-         longer required as a third-party dependancy. (patch by wj32)
+- * #117: added support for Windows 2000.
+- * #123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a
+-         new 'interval' parameter.
+- * #129: per-process number of threads.
+-
+-BUGFIXES
+-
+- * #80: fixed warnings when installing psutil with easy_install.
+- * #81: psutil fails to compile with Visual Studio.
+- * #94: suspend() raises OSError instead of AccessDenied.
+- * #86: psutil didn't compile against FreeBSD 6.x.
+- * #102: orphaned process handles obtained by using OpenProcess in C were
+-         left behind every time Process class was instantiated.
+- * #111: path and name Process properties report truncated or erroneous
+-         values on UNIX.
+- * #120: cpu_percent() always returning 100% on OS X.
+- * #112: uid and gid properties don't change if process changes effective
+-         user/group id at some point.
+- * #126: ppid, uid, gid, name, exe, cmdline and create_time properties are
+-         no longer cached and correctly raise NoSuchProcess exception if the process
+-         disappears.
+-
+-API CHANGES
+-
+- * psutil.Process.path property is deprecated and works as an alias for "exe"
+-   property.
+- * psutil.Process.kill(): signal argument was removed - to send a signal to the
+-   process use send_signal(signal) method instead.
+- * psutil.Process.get_memory_info() returns a nametuple instead of a tuple.
+- * psutil.cpu_times() returns a nametuple instead of a tuple.
+- * New psutil.Process methods: get_open_files(), get_connections(),
+-   send_signal() and terminate().
+- * ppid, uid, gid, name, exe, cmdline and create_time properties are no longer
+-   cached and raise NoSuchProcess exception if process disappears.
+- * psutil.cpu_percent() no longer returns immediately (see issue 123).
+- * psutil.Process.get_cpu_percent() and psutil.cpu_percent() no longer returns
+-   immediately by default (see issue 123).
+-
+-
+-0.1.3 - 2010-03-02
+-------------------
+-
+-NEW FEATURES
+-
+- * #14: per-process username
+- * #51: per-process current working directory (Windows and Linux only)
+- * #59: Process.is_running() is now 10 times faster
+- * #61: added supoprt for FreeBSD 64 bit
+- * #71: implemented suspend/resume process
+- * #75: python 3 support
+-
+-BUGFIXES
+-
+- * #36: process cpu_times() and memory_info() functions succeeded also for
+-        dead processes while a NoSuchProcess exception is supposed to be raised.
+- * #48: incorrect size for mib array defined in getcmdargs for BSD
+- * #49: possible memory leak due to missing free() on error condition on
+- * #50: fixed getcmdargs() memory fragmentation on BSD
+- * #55: test_pid_4 was failing on Windows Vista
+- * #57: some unit tests were failing on systems where no swap memory is
+-        available
+- * #58: is_running() is now called before kill() to make sure we are going
+-        to kill the correct process.
+- * #73: virtual memory size reported on OS X includes shared library size
+- * #77: NoSuchProcess wasn't raised on Process.create_time if kill() was
+-        used first.
+-
+-
+-0.1.2 - 2009-05-06
+-------------------
+-
+-NEW FEATURES
+-
+- * #32: Per-process CPU user/kernel times
+- * #33: Process create time
+- * #34: Per-process CPU utilization percentage
+- * #38: Per-process memory usage (bytes)
+- * #41: Per-process memory utilization (percent)
+- * #39: System uptime
+- * #43: Total system virtual memory
+- * #46: Total system physical memory
+- * #44: Total system used/free virtual and physical memory
+-
+-BUGFIXES
+-
+- * #36: [Windows] NoSuchProcess not raised when accessing timing methods.
+- * #40: test_get_cpu_times() failing on FreeBSD and OS X.
+- * #42: [Windows] get_memory_percent() raises AccessDenied.
+-
+-
+-0.1.1 - 2009-03-06
+-------------------
+-
+-NEW FEATURES
+-
+- * #4: FreeBSD support for all functions of psutil
+- * #9: Process.uid and Process.gid now retrieve process UID and GID.
+- * #11: Support for parent/ppid - Process.parent property returns a
+-        Process object representing the parent process, and Process.ppid returns
+-        the parent PID.
+- * #12 & 15:
+-        NoSuchProcess exception now raised when creating an object
+-        for a nonexistent process, or when retrieving information about a process
+-        that has gone away.
+- * #21: AccessDenied exception created for raising access denied errors
+-        from OSError or WindowsError on individual platforms.
+- * #26: psutil.process_iter() function to iterate over processes as
+-        Process objects with a generator.
+- * #?:  Process objects can now also be compared with == operator for equality
+-        (PID, name, command line are compared).
+-
+-BUGFIXES
+-
+- * #16: [Windows] Special case for "System Idle Process" (PID 0) which
+-        otherwise would return an "invalid parameter" exception.
+- * #17: get_process_list() ignores NoSuchProcess and AccessDenied
+-        exceptions during building of the list.
+- * #22: [Windows] Process(0).kill() was failing with an unset exception.
+- * #23: Special case for pid_exists(0)
+- * #24: [Windows] Process(0).kill() now raises AccessDenied exception instead of
+-        WindowsError.
+- * #30: psutil.get_pid_list() was returning two instances of PID 0 on OS
+-        X and FreeBSD platforms.
+-
+-
+-0.1.0 - 2009-01-27
+-------------------
+-
+- * Initial release.
+--- mozjs-24.2.0/js/src/python/psutil/HISTORY.rst	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/HISTORY.rst	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,978 @@
++Bug tracker at https://github.com/giampaolo/psutil/issues
++
++3.0.1 - 2015-06-18
++==================
++
++**Bug fixes**
++
++- #632: [Linux] better error message if cannot parse process UNIX connections.
++- #634: [Linux] Proces.cmdline() does not include empty string arguments.
++- #635: [UNIX] crash on module import if 'enum' package is installed on python
++  < 3.4.
++
++
++3.0.0 - 2015-06-13
++==================
++
++**Enhancements**
++
++- #250: new psutil.net_if_stats() returning NIC statistics (isup, duplex,
++  speed, MTU).
++- #376: new psutil.net_if_addrs() returning all NIC addresses a-la ifconfig.
++- #469: on Python >= 3.4 ``IOPRIO_CLASS_*`` and ``*_PRIORITY_CLASS`` constants
++  returned by psutil.Process' ionice() and nice() methods are enums instead of
++  plain integers.
++- #581: add .gitignore. (patch by Gabi Davar)
++- #582: connection constants returned by psutil.net_connections() and
++  psutil.Process.connections() were turned from int to enums on Python > 3.4.
++- #587: Move native extension into the package.
++- #589: Process.cpu_affinity() accepts any kind of iterable (set, tuple, ...),
++  not only lists.
++- #594: all deprecated APIs were removed.
++- #599: [Windows] process name() can now be determined for all processes even
++  when running as a limited user.
++- #602: pre-commit GIT hook.
++- #629: enhanced support for py.test and nose test discovery and tests run.
++- #616: [Windows] Add inet_ntop function for Windows XP.
++
++**Bug fixes**
++
++- #428: [all UNIXes except Linux] correct handling of zombie processes;
++  introduced new ZombieProcess exception class.
++- #512: [BSD] fix segfault in net_connections().
++- #555: [Linux] psutil.users() correctly handles ":0" as an alias for
++  "localhost"
++- #579: [Windows] Fixed open_files() for PID>64K.
++- #579: [Windows] fixed many compiler warnings.
++- #585: [FreeBSD] net_connections() may raise KeyError.
++- #586: [FreeBSD] cpu_affinity() segfaults on set in case an invalid CPU
++  number is provided.
++- #593: [FreeBSD] Process().memory_maps() segfaults.
++- #606: Process.parent() may swallow NoSuchProcess exceptions.
++- #611: [SunOS] net_io_counters has send and received swapped
++- #614: [Linux]: cpu_count(logical=False) return the number of physical CPUs
++  instead of physical cores.
++- #618: [SunOS] swap tests fail on Solaris when run as normal user
++- #628: [Linux] Process.name() truncates process name in case it contains
++  spaces or parentheses.
++
++
++2.2.1 - 2015-02-02
++==================
++
++**Bug fixes**
++
++- #496: [Linux] fix "ValueError: ambiguos inode with multiple PIDs references"
++  (patch by Bruno Binet)
++
++
++2.2.0 - 2015-01-06
++==================
++
++**Enhancements**
++
++- #521: drop support for Python 2.4 and 2.5.
++- #553: new examples/pstree.py script.
++- #564: C extension version mismatch in case the user messed up with psutil
++  installation or with sys.path is now detected at import time.
++- #568: New examples/pidof.py script.
++- #569: [FreeBSD] add support for process CPU affinity.
++
++**Bug fixes**
++
++- #496: [Solaris] can't import psutil.
++- #547: [UNIX] Process.username() may raise KeyError if UID can't be resolved.
++- #551: [Windows] get rid of the unicode hack for net_io_counters() NIC names.
++- #556: [Linux] lots of file handles were left open.
++- #561: [Linux] net_connections() might skip some legitimate UNIX sockets.
++  (patch by spacewander)
++- #565: [Windows] use proper encoding for psutil.Process.username() and
++  psutil.users(). (patch by Sylvain Mouquet)
++- #567: [Linux] in the alternative implementation of CPU affinity PyList_Append
++  and Py_BuildValue return values are not checked.
++- #569: [FreeBSD] fix memory leak in psutil.cpu_count(logical=False).
++- #571: [Linux] Process.open_files() might swallow AccessDenied exceptions and
++  return an incomplete list of open files.
++
++
++2.1.3 - 2014-09-26
++==================
++
++- #536: [Linux]: fix "undefined symbol: CPU_ALLOC" compilation error.
++
++
++2.1.2 - 2014-09-21
++==================
++
++**Enhancements**
++
++- #407: project moved from Google Code to Github; code moved from Mercurial
++  to Git.
++- #492: use tox to run tests on multiple python versions.  (patch by msabramo)
++- #505: [Windows] distribution as wheel packages.
++- #511: new examples/ps.py sample code.
++
++**Bug fixes**
++
++- #340: [Windows] Process.get_open_files() no longer hangs.  (patch by
++  Jeff Tang)
++- #501: [Windows] disk_io_counters() may return negative values.
++- #503: [Linux] in rare conditions Process exe(), open_files() and
++  connections() methods can raise OSError(ESRCH) instead of NoSuchProcess.
++- #504: [Linux] can't build RPM packages via setup.py
++- #506: [Linux] python 2.4 support was broken.
++- #522: [Linux] Process.cpu_affinity() might return EINVAL.  (patch by David
++  Daeschler)
++- #529: [Windows] Process.exe() may raise unhandled WindowsError exception
++  for PIDs 0 and 4.  (patch by Jeff Tang)
++- #530: [Linux] psutil.disk_io_counters() may crash on old Linux distros
++  (< 2.6.5)  (patch by Yaolong Huang)
++- #533: [Linux] Process.memory_maps() may raise TypeError on old Linux distros.
++
++
++2.1.1 - 2014-04-30
++==================
++
++**Bug fixes**
++
++- #446: [Windows] fix encoding error when using net_io_counters() on Python 3.
++  (patch by Szigeti Gabor Niif)
++- #460: [Windows] net_io_counters() wraps after 4G.
++- #491: [Linux] psutil.net_connections() exceptions. (patch by Alexander Grothe)
++
++
++2.1.0 - 2014-04-08
++==================
++
++**Enhancements**
++
++- #387: system-wide open connections a-la netstat.
++
++**Bug fixes**
++
++- #421: [Solaris] psutil does not compile on SunOS 5.10 (patch by Naveed
++  Roudsari)
++- #489: [Linux] psutil.disk_partitions() return an empty list.
++
++
++2.0.0 - 2014-03-10
++==================
++
++**Enhancements**
++
++- #424: [Windows] installer for Python 3.X 64 bit.
++- #427: number of logical and physical CPUs (psutil.cpu_count()).
++- #447: psutil.wait_procs() timeout parameter is now optional.
++- #452: make Process instances hashable and usable with set()s.
++- #453: tests on Python < 2.7 require unittest2 module.
++- #459: add a make file for running tests and other repetitive tasks (also
++  on Windows).
++- #463: make timeout parameter of cpu_percent* functions default to 0.0 'cause
++  it's a common trap to introduce slowdowns.
++- #468: move documentation to readthedocs.com.
++- #477: process cpu_percent() is about 30% faster.  (suggested by crusaderky)
++- #478: [Linux] almost all APIs are about 30% faster on Python 3.X.
++- #479: long deprecated psutil.error module is gone; exception classes now
++  live in "psutil" namespace only.
++
++**Bug fixes**
++
++- #193: psutil.Popen constructor can throw an exception if the spawned process
++  terminates quickly.
++- #340: [Windows] process get_open_files() no longer hangs.  (patch by
++  [email protected])
++- #443: [Linux] fix a potential overflow issue for Process.set_cpu_affinity()
++  on systems with more than 64 CPUs.
++- #448: [Windows] get_children() and ppid() memory leak (patch by Ulrich
++  Klank).
++- #457: [POSIX] pid_exists() always returns True for PID 0.
++- #461: namedtuples are not pickle-able.
++- #466: [Linux] process exe improper null bytes handling.  (patch by
++  Gautam Singh)
++- #470: wait_procs() might not wait.  (patch by crusaderky)
++- #471: [Windows] process exe improper unicode handling. (patch by
++  [email protected])
++- #473: psutil.Popen.wait() does not set returncode attribute.
++- #474: [Windows] Process.cpu_percent() is no longer capped at 100%.
++- #476: [Linux] encoding error for process name and cmdline.
++
++**API changes**
++
++For the sake of consistency a lot of psutil APIs have been renamed.
++In most cases accessing the old names will work but it will cause a
++DeprecationWarning.
++
++- psutil.* module level constants have being replaced by functions:
++
++  +-----------------------+-------------------------------+
++  | Old name              | Replacement                   |
++  +=======================+===============================+
++  | psutil.NUM_CPUS       | psutil.cpu_cpunt()            |
++  +-----------------------+-------------------------------+
++  | psutil.BOOT_TIME      | psutil.boot_time()            |
++  +-----------------------+-------------------------------+
++  | psutil.TOTAL_PHYMEM   | psutil.virtual_memory().total |
++  +-----------------------+-------------------------------+
++
++- Renamed psutil.* functions:
++
++  +--------------------------+-------------------------------+
++  | Old name                 | Replacement                   |
++  +==========================+===============================+
++  | - psutil.get_pid_list()  | psutil.pids()                 |
++  +--------------------------+-------------------------------+
++  | - psutil.get_users()     | psutil.users()                |
++  +--------------------------+-------------------------------+
++  | - psutil.get_boot_time() | psutil.boot_time()            |
++  +--------------------------+-------------------------------+
++
++- All psutil.Process ``get_*`` methods lost the ``get_`` prefix.
++  get_ext_memory_info() renamed to memory_info_ex().
++  Assuming "p = psutil.Process()":
++
++  +--------------------------+----------------------+
++  | Old name                 | Replacement          |
++  +==========================+======================+
++  | p.get_children()         | p.children()         |
++  +--------------------------+----------------------+
++  | p.get_connections()      | p.connections()      |
++  +--------------------------+----------------------+
++  | p.get_cpu_affinity()     | p.cpu_affinity()     |
++  +--------------------------+----------------------+
++  | p.get_cpu_percent()      | p.cpu_percent()      |
++  +--------------------------+----------------------+
++  | p.get_cpu_times()        | p.cpu_times()        |
++  +--------------------------+----------------------+
++  | p.get_ext_memory_info()  | p.memory_info_ex()   |
++  +--------------------------+----------------------+
++  | p.get_io_counters()      | p.io_counters()      |
++  +--------------------------+----------------------+
++  | p.get_ionice()           | p.ionice()           |
++  +--------------------------+----------------------+
++  | p.get_memory_info()      | p.memory_info()      |
++  +--------------------------+----------------------+
++  | p.get_memory_maps()      | p.memory_maps()      |
++  +--------------------------+----------------------+
++  | p.get_memory_percent()   | p.memory_percent()   |
++  +--------------------------+----------------------+
++  | p.get_nice()             | p.nice()             |
++  +--------------------------+----------------------+
++  | p.get_num_ctx_switches() | p.num_ctx_switches() |
++  +--------------------------+----------------------+
++  | p.get_num_fds()          | p.num_fds()          |
++  +--------------------------+----------------------+
++  | p.get_num_threads()      | p.num_threads()      |
++  +--------------------------+----------------------+
++  | p.get_open_files()       | p.open_files()       |
++  +--------------------------+----------------------+
++  | p.get_rlimit()           | p.rlimit()           |
++  +--------------------------+----------------------+
++  | p.get_threads()          | p.threads()          |
++  +--------------------------+----------------------+
++  | p.getcwd()               | p.cwd()              |
++  +--------------------------+----------------------+
++
++- All psutil.Process ``set_*`` methods lost the ``set_`` prefix.
++  Assuming "p = psutil.Process()":
++
++  +----------------------+---------------------------------+
++  | Old name             | Replacement                     |
++  +======================+=================================+
++  | p.set_nice()         | p.nice(value)                   |
++  +----------------------+---------------------------------+
++  | p.set_ionice()       | p.ionice(ioclass, value=None)   |
++  +----------------------+---------------------------------+
++  | p.set_cpu_affinity() | p.cpu_affinity(cpus)            |
++  +----------------------+---------------------------------+
++  | p.set_rlimit()       | p.rlimit(resource, limits=None) |
++  +----------------------+---------------------------------+
++
++- Except for 'pid' all psutil.Process class properties have been turned into
++  methods. This is the only case which there are no aliases.
++  Assuming "p = psutil.Process()":
++
++  +---------------+-----------------+
++  | Old name      | Replacement     |
++  +===============+=================+
++  | p.name        | p.name()        |
++  +---------------+-----------------+
++  | p.parent      | p.parent()      |
++  +---------------+-----------------+
++  | p.ppid        | p.ppid()        |
++  +---------------+-----------------+
++  | p.exe         | p.exe()         |
++  +---------------+-----------------+
++  | p.cmdline     | p.cmdline()     |
++  +---------------+-----------------+
++  | p.status      | p.status()      |
++  +---------------+-----------------+
++  | p.uids        | p.uids()        |
++  +---------------+-----------------+
++  | p.gids        | p.gids()        |
++  +---------------+-----------------+
++  | p.username    | p.username()    |
++  +---------------+-----------------+
++  | p.create_time | p.create_time() |
++  +---------------+-----------------+
++
++- timeout parameter of cpu_percent* functions defaults to 0.0 instead of 0.1.
++- long deprecated psutil.error module is gone; exception classes now live in
++  "psutil" namespace only.
++- Process instances' "retcode" attribute returned by psutil.wait_procs() has
++  been renamed to "returncode" for consistency with subprocess.Popen.
++
++
++1.2.1 - 2013-11-25
++==================
++
++**Bug fixes**
++
++- #348: [Windows XP] fixed "ImportError: DLL load failed" occurring on module
++  import.
++- #425: [Solaris] crash on import due to failure at determining BOOT_TIME.
++- #443: [Linux] can't set CPU affinity on systems with more than 64 cores.
++
++
++1.2.0 - 2013-11-20
++==================
++
++**Enhancements**
++
++- #439: assume os.getpid() if no argument is passed to psutil.Process
++  constructor.
++- #440: new psutil.wait_procs() utility function which waits for multiple
++  processes to terminate.
++
++**Bug fixes**
++
++- #348: [Windows XP/Vista] fix "ImportError: DLL load failed" occurring on
++  module import.
++
++
++1.1.3 - 2013-11-07
++==================
++
++**Bug fixes**
++
++- #442: [Linux] psutil won't compile on certain version of Linux because of
++  missing prlimit(2) syscall.
++
++
++1.1.2 - 2013-10-22
++==================
++
++**Bug fixes**
++
++- #442: [Linux] psutil won't compile on Debian 6.0 because of missing
++  prlimit(2) syscall.
++
++
++1.1.1 - 2013-10-08
++==================
++
++**Bug fixes**
++
++- #442: [Linux] psutil won't compile on kernels < 2.6.36 due to missing
++  prlimit(2) syscall.
++
++
++1.1.0 - 2013-09-28
++==================
++
++**Enhancements**
++
++- #410: host tar.gz and windows binary files are on PYPI.
++- #412: [Linux] get/set process resource limits.
++- #415: [Windows] Process.get_children() is an order of magnitude faster.
++- #426: [Windows] Process.name is an order of magnitude faster.
++- #431: [UNIX] Process.name is slightly faster because it unnecessarily
++  retrieved also process cmdline.
++
++**Bug fixes**
++
++- #391: [Windows] psutil.cpu_times_percent() returns negative percentages.
++- #408: STATUS_* and CONN_* constants don't properly serialize on JSON.
++- #411: [Windows] examples/disk_usage.py may pop-up a GUI error.
++- #413: [Windows] Process.get_memory_info() leaks memory.
++- #414: [Windows] Process.exe on Windows XP may raise ERROR_INVALID_PARAMETER.
++- #416: psutil.disk_usage() doesn't work well with unicode path names.
++- #430: [Linux] process IO counters report wrong number of r/w syscalls.
++- #435: [Linux] psutil.net_io_counters() might report erreneous NIC names.
++- #436: [Linux] psutil.net_io_counters() reports a wrong 'dropin' value.
++
++**API changes**
++
++- #408: turn STATUS_* and CONN_* constants into plain Python strings.
++
++
++1.0.1 - 2013-07-12
++==================
++
++**Bug fixes**
++
++- #405: network_io_counters(pernic=True) no longer works as intended in 1.0.0.
++
++
++1.0.0 - 2013-07-10
++==================
++
++**Enhancements**
++
++- #18:  Solaris support (yay!)  (thanks Justin Venus)
++- #367: Process.get_connections() 'status' strings are now constants.
++- #380: test suite exits with non-zero on failure.  (patch by floppymaster)
++- #391: introduce unittest2 facilities and provide workarounds if unittest2
++  is not installed (python < 2.7).
++
++**Bug fixes**
++
++- #374: [Windows] negative memory usage reported if process uses a lot of
++  memory.
++- #379: [Linux] Process.get_memory_maps() may raise ValueError.
++- #394: [OSX] Mapped memory regions report incorrect file name.
++- #404: [Linux] sched_*affinity() are implicitly declared. (patch by Arfrever)
++
++**API changes**
++
++- Process.get_connections() 'status' field is no longer a string but a
++  constant object (psutil.CONN_*).
++- Process.get_connections() 'local_address' and 'remote_address' fields
++  renamed to 'laddr' and 'raddr'.
++- psutil.network_io_counters() renamed to psutil.net_io_counters().
++
++
++0.7.1 - 2013-05-03
++==================
++
++**Bug fixes**
++
++- #325: [BSD] psutil.virtual_memory() can raise SystemError.
++  (patch by Jan Beich)
++- #370: [BSD] Process.get_connections() requires root.  (patch by John Baldwin)
++- #372: [BSD] different process methods raise NoSuchProcess instead of
++  AccessDenied.
++
++
++0.7.0 - 2013-04-12
++==================
++
++**Enhancements**
++
++- #233: code migrated to Mercurial (yay!)
++- #246: psutil.error module is deprecated and scheduled for removal.
++- #328: [Windows] process IO nice/priority support.
++- #359: psutil.get_boot_time()
++- #361: [Linux] psutil.cpu_times() now includes new 'steal', 'guest' and
++  'guest_nice' fields available on recent Linux kernels.
++  Also, psutil.cpu_percent() is more accurate.
++- #362: cpu_times_percent() (per-CPU-time utilization as a percentage)
++
++**Bug fixes**
++
++- #234: [Windows] disk_io_counters() fails to list certain disks.
++- #264: [Windows] use of psutil.disk_partitions() may cause a message box to
++  appear.
++- #313: [Linux] psutil.virtual_memory() and psutil.swap_memory() can crash on
++  certain exotic Linux flavors having an incomplete /proc interface.
++  If that's the case we now set the unretrievable stats to 0 and raise a
++  RuntimeWarning.
++- #315: [OSX] fix some compilation warnings.
++- #317: [Windows] cannot set process CPU affinity above 31 cores.
++- #319: [Linux] process get_memory_maps() raises KeyError 'Anonymous' on Debian
++  squeeze.
++- #321: [UNIX] Process.ppid property is no longer cached as the kernel may set
++  the ppid to 1 in case of a zombie process.
++- #323: [OSX] disk_io_counters()'s read_time and write_time parameters were
++  reporting microseconds not milliseconds.  (patch by Gregory Szorc)
++- #331: Process cmdline is no longer cached after first acces as it may change.
++- #333: [OSX] Leak of Mach ports on OS X (patch by [email protected])
++- #337: [Linux] process methods not working because of a poor /proc
++  implementation will raise NotImplementedError rather than RuntimeError
++  and Process.as_dict() will not blow up.  (patch by Curtin1060)
++- #338: [Linux] disk_io_counters() fails to find some disks.
++- #339: [FreeBSD] get_pid_list() can allocate all the memory on system.
++- #341: [Linux] psutil might crash on import due to error in retrieving system
++  terminals map.
++- #344: [FreeBSD] swap_memory() might return incorrect results due to
++  kvm_open(3) not being called. (patch by Jean Sebastien)
++- #338: [Linux] disk_io_counters() fails to find some disks.
++- #351: [Windows] if psutil is compiled with mingw32 (provided installers for
++  py2.4 and py2.5 are) disk_io_counters() will fail. (Patch by m.malycha)
++- #353: [OSX] get_users() returns an empty list on OSX 10.8.
++- #356: Process.parent now checks whether parent PID has been reused in which
++  case returns None.
++- #365: Process.set_nice() should check PID has not been reused by another
++  process.
++- #366: [FreeBSD] get_memory_maps(), get_num_fds(), get_open_files() and
++  getcwd() Process methods raise RuntimeError instead of AccessDenied.
++
++**API changes**
++
++- Process.cmdline property is no longer cached after first access.
++- Process.ppid property is no longer cached after first access.
++- [Linux] Process methods not working because of a poor /proc implementation
++  will raise NotImplementedError instead of RuntimeError.
++- psutil.error module is deprecated and scheduled for removal.
++
++
++0.6.1 - 2012-08-16
++==================
++
++**Enhancements**
++
++- #316: process cmdline property now makes a better job at guessing the process
++  executable from the cmdline.
++
++**Bug fixes**
++
++- #316: process exe was resolved in case it was a symlink.
++- #318: python 2.4 compatibility was broken.
++
++**API changes**
++
++- process exe can now return an empty string instead of raising AccessDenied.
++- process exe is no longer resolved in case it's a symlink.
++
++
++0.6.0 - 2012-08-13
++==================
++
++**Enhancements**
++
++- #216: [POSIX] get_connections() UNIX sockets support.
++- #220: [FreeBSD] get_connections() has been rewritten in C and no longer
++  requires lsof.
++- #222: [OSX] add support for process cwd.
++- #261: process extended memory info.
++- #295: [OSX] process executable path is now determined by asking the OS
++  instead of being guessed from process cmdline.
++- #297: [OSX] the Process methods below were always raising AccessDenied for
++  any process except the current one. Now this is no longer true. Also
++  they are 2.5x faster.
++  - name
++  - get_memory_info()
++  - get_memory_percent()
++  - get_cpu_times()
++  - get_cpu_percent()
++  - get_num_threads()
++- #300: examples/pmap.py script.
++- #301: process_iter() now yields processes sorted by their PIDs.
++- #302: process number of voluntary and involuntary context switches.
++- #303: [Windows] the Process methods below were always raising AccessDenied
++  for any process not owned by current user. Now this is no longer true:
++  - create_time
++  - get_cpu_times()
++  - get_cpu_percent()
++  - get_memory_info()
++  - get_memory_percent()
++  - get_num_handles()
++  - get_io_counters()
++- #305: add examples/netstat.py script.
++- #311: system memory functions has been refactorized and rewritten and now
++  provide a more detailed and consistent representation of the system
++  memory. New psutil.virtual_memory() function provides the following
++  memory amounts:
++  - total
++  - available
++  - percent
++  - used
++  - active [POSIX]
++  - inactive [POSIX]
++  - buffers (BSD, Linux)
++  - cached (BSD, OSX)
++  - wired (OSX, BSD)
++  - shared [FreeBSD]
++  New psutil.swap_memory() provides:
++  - total
++  - used
++  - free
++  - percent
++  - sin (no. of bytes the system has swapped in from disk (cumulative))
++  - sout (no. of bytes the system has swapped out from disk (cumulative))
++  All old memory-related functions are deprecated.
++  Also two new example scripts were added:  free.py and meminfo.py.
++- #312: psutil.network_io_counters() namedtuple includes 4 new fields:
++  errin, errout dropin and dropout, reflecting the number of packets
++  dropped and with errors.
++
++**Bugfixes**
++
++- #298: [OSX and BSD] memory leak in get_num_fds().
++- #299: potential memory leak every time PyList_New(0) is used.
++- #303: [Windows] potential heap corruption in get_num_threads() and
++  get_status() Process methods.
++- #305: [FreeBSD] psutil can't compile on FreeBSD 9 due to removal of utmp.h.
++- #306: at C level, errors are not checked when invoking Py* functions which
++  create or manipulate Python objects leading to potential memory related
++  errors and/or segmentation faults.
++- #307: [FreeBSD] values returned by psutil.network_io_counters() are wrong.
++- #308: [BSD / Windows] psutil.virtmem_usage() wasn't actually returning
++  information about swap memory usage as it was supposed to do. It does
++  now.
++- #309: get_open_files() might not return files which can not be accessed
++  due to limited permissions. AccessDenied is now raised instead.
++
++**API changes**
++
++- psutil.phymem_usage() is deprecated       (use psutil.virtual_memory())
++- psutil.virtmem_usage() is deprecated      (use psutil.swap_memory())
++- psutil.phymem_buffers() on Linux is deprecated  (use psutil.virtual_memory())
++- psutil.cached_phymem() on Linux is deprecated   (use psutil.virtual_memory())
++- [Windows and BSD] psutil.virtmem_usage() now returns information about swap
++  memory instead of virtual memory.
++
++
++0.5.1 - 2012-06-29
++==================
++
++**Enhancements**
++
++- #293: [Windows] process executable path is now determined by asking the OS
++  instead of being guessed from process cmdline.
++
++**Bugfixes**
++
++- #292: [Linux] race condition in process files/threads/connections.
++- #294: [Windows] Process CPU affinity is only able to set CPU #0.
++
++
++0.5.0 - 2012-06-27
++==================
++
++**Enhancements**
++
++- #195: [Windows] number of handles opened by process.
++- #209: psutil.disk_partitions() now provides also mount options.
++- #229: list users currently connected on the system (psutil.get_users()).
++- #238: [Linux, Windows] process CPU affinity (get and set).
++- #242: Process.get_children(recursive=True): return all process
++  descendants.
++- #245: [POSIX] Process.wait() incrementally consumes less CPU cycles.
++- #257: [Windows] removed Windows 2000 support.
++- #258: [Linux] Process.get_memory_info() is now 0.5x faster.
++- #260: process's mapped memory regions. (Windows patch by wj32.64, OSX patch
++  by Jeremy Whitlock)
++- #262: [Windows] psutil.disk_partitions() was slow due to inspecting the
++  floppy disk drive also when "all" argument was False.
++- #273: psutil.get_process_list() is deprecated.
++- #274: psutil no longer requires 2to3 at installation time in order to work
++  with Python 3.
++- #278: new Process.as_dict() method.
++- #281: ppid, name, exe, cmdline and create_time properties of Process class
++  are now cached after being accessed.
++- #282: psutil.STATUS_* constants can now be compared by using their string
++  representation.
++- #283: speedup Process.is_running() by caching its return value in case the
++  process is terminated.
++- #284: [POSIX] per-process number of opened file descriptors.
++- #287: psutil.process_iter() now caches Process instances between calls.
++- #290: Process.nice property is deprecated in favor of new get_nice() and
++  set_nice() methods.
++
++**Bugfixes**
++
++- #193: psutil.Popen constructor can throw an exception if the spawned process
++  terminates quickly.
++- #240: [OSX] incorrect use of free() for Process.get_connections().
++- #244: [POSIX] Process.wait() can hog CPU resources if called against a
++  process which is not our children.
++- #248: [Linux] psutil.network_io_counters() might return erroneous NIC names.
++- #252: [Windows] process getcwd() erroneously raise NoSuchProcess for
++  processes owned by another user.  It now raises AccessDenied instead.
++- #266: [Windows] psutil.get_pid_list() only shows 1024 processes.
++  (patch by Amoser)
++- #267: [OSX] Process.get_connections() - an erroneous remote address was
++  returned. (Patch by Amoser)
++- #272: [Linux] Porcess.get_open_files() - potential race condition can lead to
++  unexpected NoSuchProcess exception.  Also, we can get incorrect reports
++  of not absolutized path names.
++- #275: [Linux] Process.get_io_counters() erroneously raise NoSuchProcess on
++  old Linux versions. Where not available it now raises
++  NotImplementedError.
++- #286: Process.is_running() doesn't actually check whether PID has been
++  reused.
++- #314: Process.get_children() can sometimes return non-children.
++
++**API changes**
++
++- Process.nice property is deprecated in favor of new get_nice() and set_nice()
++  methods.
++- psutil.get_process_list() is deprecated.
++- ppid, name, exe, cmdline and create_time properties of Process class are now
++  cached after being accessed, meaning NoSuchProcess will no longer be raised
++  in case the process is gone in the meantime.
++- psutil.STATUS_* constants can now be compared by using their string
++  representation.
++
++
++0.4.1 - 2011-12-14
++==================
++
++**Bugfixes**
++
++- #228: some example scripts were not working with python 3.
++- #230: [Windows / OSX] memory leak in Process.get_connections().
++- #232: [Linux] psutil.phymem_usage() can report erroneous values which are
++  different than "free" command.
++- #236: [Windows] memory/handle leak in Process's get_memory_info(),
++  suspend() and resume() methods.
++
++
++0.4.0 - 2011-10-29
++==================
++
++**Enhancements**
++
++- #150: network I/O counters. (OSX and Windows patch by Jeremy Whitlock)
++- #154: [FreeBSD] add support for process getcwd()
++- #157: [Windows] provide installer for Python 3.2 64-bit.
++- #198: Process.wait(timeout=0) can now be used to make wait() return
++  immediately.
++- #206: disk I/O counters. (OSX and Windows patch by Jeremy Whitlock)
++- #213: examples/iotop.py script.
++- #217: Process.get_connections() now has a "kind" argument to filter
++  for connections with different criteria.
++- #221: [FreeBSD] Process.get_open_files has been rewritten in C and no longer
++  relies on lsof.
++- #223: examples/top.py script.
++- #227: examples/nettop.py script.
++
++**Bugfixes**
++
++- #135: [OSX] psutil cannot create Process object.
++- #144: [Linux] no longer support 0 special PID.
++- #188: [Linux] psutil import error on Linux ARM architectures.
++- #194: [POSIX] psutil.Process.get_cpu_percent() now reports a percentage over
++  100 on multicore processors.
++- #197: [Linux] Process.get_connections() is broken on platforms not
++  supporting IPv6.
++- #200: [Linux] psutil.NUM_CPUS not working on armel and sparc architectures
++  and causing crash on module import.
++- #201: [Linux] Process.get_connections() is broken on big-endian
++  architectures.
++- #211: Process instance can unexpectedly raise NoSuchProcess if tested for
++  equality with another object.
++- #218: [Linux] crash at import time on Debian 64-bit because of a missing
++  line in /proc/meminfo.
++- #226: [FreeBSD] crash at import time on FreeBSD 7 and minor.
++
++
++0.3.0 - 2011-07-08
++==================
++
++**Enhancements**
++
++- #125: system per-cpu percentage utilization and times.
++- #163: per-process associated terminal (TTY).
++- #171: added get_phymem() and get_virtmem() functions returning system
++  memory information (total, used, free) and memory percent usage.
++  total_* avail_* and used_* memory functions are deprecated.
++- #172: disk usage statistics.
++- #174: mounted disk partitions.
++- #179: setuptools is now used in setup.py
++
++**Bugfixes**
++
++- #159: SetSeDebug() does not close handles or unset impersonation on return.
++- #164: [Windows] wait function raises a TimeoutException when a process
++  returns -1 .
++- #165: process.status raises an unhandled exception.
++- #166: get_memory_info() leaks handles hogging system resources.
++- #168: psutil.cpu_percent() returns erroneous results when used in
++  non-blocking mode.  (patch by Philip Roberts)
++- #178: OSX - Process.get_threads() leaks memory
++- #180: [Windows] Process's get_num_threads() and get_threads() methods can
++  raise NoSuchProcess exception while process still exists.
++
++
++0.2.1 - 2011-03-20
++==================
++
++**Enhancements**
++
++- #64: per-process I/O counters.
++- #116: per-process wait() (wait for process to terminate and return its exit
++  code).
++- #134: per-process get_threads() returning information (id, user and kernel
++  times) about threads opened by process.
++- #136: process executable path on FreeBSD is now determined by asking the
++  kernel instead of guessing it from cmdline[0].
++- #137: per-process real, effective and saved user and group ids.
++- #140: system boot time.
++- #142: per-process get and set niceness (priority).
++- #143: per-process status.
++- #147: per-process I/O nice (priority) - Linux only.
++- #148: psutil.Popen class which tidies up subprocess.Popen and psutil.Process
++  in a unique interface.
++- #152: [OSX] get_process_open_files() implementation has been rewritten
++  in C and no longer relies on lsof resulting in a 3x speedup.
++- #153: [OSX] get_process_connection() implementation has been rewritten
++  in C and no longer relies on lsof resulting in a 3x speedup.
++
++**Bugfixes**
++
++- #83:  process cmdline is empty on OSX 64-bit.
++- #130: a race condition can cause IOError exception be raised on
++  Linux if process disappears between open() and subsequent read() calls.
++- #145: WindowsError was raised instead of psutil.AccessDenied when using
++  process resume() or suspend() on Windows.
++- #146: 'exe' property on Linux can raise TypeError if path contains NULL
++  bytes.
++- #151: exe and getcwd() for PID 0 on Linux return inconsistent data.
++
++**API changes**
++
++- Process "uid" and "gid" properties are deprecated in favor of "uids" and
++  "gids" properties.
++
++
++0.2.0 - 2010-11-13
++==================
++
++**Enhancements**
++
++- #79: per-process open files.
++- #88: total system physical cached memory.
++- #88: total system physical memory buffers used by the kernel.
++- #91: per-process send_signal() and terminate() methods.
++- #95: NoSuchProcess and AccessDenied exception classes now provide "pid",
++  "name" and "msg" attributes.
++- #97: per-process children.
++- #98: Process.get_cpu_times() and Process.get_memory_info now return
++  a namedtuple instead of a tuple.
++- #103: per-process opened TCP and UDP connections.
++- #107: add support for Windows 64 bit. (patch by cjgohlke)
++- #111: per-process executable name.
++- #113: exception messages now include process name and pid.
++- #114: process username Windows implementation has been rewritten in pure
++  C and no longer uses WMI resulting in a big speedup. Also, pywin32 is no
++  longer required as a third-party dependancy. (patch by wj32)
++- #117: added support for Windows 2000.
++- #123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a
++  new 'interval' parameter.
++- #129: per-process number of threads.
++
++**Bugfixes**
++
++- #80: fixed warnings when installing psutil with easy_install.
++- #81: psutil fails to compile with Visual Studio.
++- #94: suspend() raises OSError instead of AccessDenied.
++- #86: psutil didn't compile against FreeBSD 6.x.
++- #102: orphaned process handles obtained by using OpenProcess in C were
++  left behind every time Process class was instantiated.
++- #111: path and name Process properties report truncated or erroneous
++  values on UNIX.
++- #120: cpu_percent() always returning 100% on OS X.
++- #112: uid and gid properties don't change if process changes effective
++  user/group id at some point.
++- #126: ppid, uid, gid, name, exe, cmdline and create_time properties are
++  no longer cached and correctly raise NoSuchProcess exception if the process
++  disappears.
++
++**API changes**
++
++- psutil.Process.path property is deprecated and works as an alias for "exe"
++  property.
++- psutil.Process.kill(): signal argument was removed - to send a signal to the
++  process use send_signal(signal) method instead.
++- psutil.Process.get_memory_info() returns a nametuple instead of a tuple.
++- psutil.cpu_times() returns a nametuple instead of a tuple.
++- New psutil.Process methods: get_open_files(), get_connections(),
++  send_signal() and terminate().
++- ppid, uid, gid, name, exe, cmdline and create_time properties are no longer
++  cached and raise NoSuchProcess exception if process disappears.
++- psutil.cpu_percent() no longer returns immediately (see issue 123).
++- psutil.Process.get_cpu_percent() and psutil.cpu_percent() no longer returns
++  immediately by default (see issue 123).
++
++
++0.1.3 - 2010-03-02
++==================
++
++**Enhancements**
++
++- #14: per-process username
++- #51: per-process current working directory (Windows and Linux only)
++- #59: Process.is_running() is now 10 times faster
++- #61: added supoprt for FreeBSD 64 bit
++- #71: implemented suspend/resume process
++- #75: python 3 support
++
++**Bugfixes**
++
++- #36: process cpu_times() and memory_info() functions succeeded also for dead
++  processes while a NoSuchProcess exception is supposed to be raised.
++- #48: incorrect size for mib array defined in getcmdargs for BSD
++- #49: possible memory leak due to missing free() on error condition on
++- #50: fixed getcmdargs() memory fragmentation on BSD
++- #55: test_pid_4 was failing on Windows Vista
++- #57: some unit tests were failing on systems where no swap memory is
++  available
++- #58: is_running() is now called before kill() to make sure we are going
++  to kill the correct process.
++- #73: virtual memory size reported on OS X includes shared library size
++- #77: NoSuchProcess wasn't raised on Process.create_time if kill() was
++  used first.
++
++
++0.1.2 - 2009-05-06
++==================
++
++**Enhancements**
++
++- #32: Per-process CPU user/kernel times
++- #33: Process create time
++- #34: Per-process CPU utilization percentage
++- #38: Per-process memory usage (bytes)
++- #41: Per-process memory utilization (percent)
++- #39: System uptime
++- #43: Total system virtual memory
++- #46: Total system physical memory
++- #44: Total system used/free virtual and physical memory
++
++**Bugfixes**
++
++- #36: [Windows] NoSuchProcess not raised when accessing timing methods.
++- #40: test_get_cpu_times() failing on FreeBSD and OS X.
++- #42: [Windows] get_memory_percent() raises AccessDenied.
++
++
++0.1.1 - 2009-03-06
++==================
++
++**Enhancements**
++
++- #4: FreeBSD support for all functions of psutil
++- #9: Process.uid and Process.gid now retrieve process UID and GID.
++- #11: Support for parent/ppid - Process.parent property returns a
++  Process object representing the parent process, and Process.ppid returns
++  the parent PID.
++- #12 & 15:
++  NoSuchProcess exception now raised when creating an object
++  for a nonexistent process, or when retrieving information about a process
++  that has gone away.
++- #21: AccessDenied exception created for raising access denied errors
++  from OSError or WindowsError on individual platforms.
++- #26: psutil.process_iter() function to iterate over processes as
++  Process objects with a generator.
++- #?:  Process objects can now also be compared with == operator for equality
++  (PID, name, command line are compared).
++
++**Bugfixes**
++
++- #16: [Windows] Special case for "System Idle Process" (PID 0) which
++  otherwise would return an "invalid parameter" exception.
++- #17: get_process_list() ignores NoSuchProcess and AccessDenied
++  exceptions during building of the list.
++- #22: [Windows] Process(0).kill() was failing with an unset exception.
++- #23: Special case for pid_exists(0)
++- #24: [Windows] Process(0).kill() now raises AccessDenied exception instead
++  of WindowsError.
++- #30: psutil.get_pid_list() was returning two instances of PID 0 on OSX and
++  FreeBSD platforms.
++
++
++0.1.0 - 2009-01-27
++==================
++
++- Initial release.
+--- mozjs-24.2.0/js/src/python/psutil/INSTALL.rst	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/INSTALL.rst	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,116 @@
++============================
++Installing using pip on UNIX
++============================
++
++The easiest way to install psutil on UNIX is by using pip (but first you might
++need to install python header files; see later).
++First install pip::
++
++    $ wget https://bootstrap.pypa.io/get-pip.py
++    $ python get-pip.py
++
++...then run::
++
++    $ pip install psutil
++
++You may need to install gcc and python header files first (see later).
++
++
++=====================
++Installing on Windows
++=====================
++
++Just get the right installer for your Python version and architecture from:
++https://pypi.python.org/pypi/psutil/#downloads
++Since wheels installers are also available you may also use pip.
++
++
++========================================
++Compiling on Windows using Visual Studio
++========================================
++
++In order to compile psutil on Windows you'll need Visual Studio (Mingw32 is
++no longer supported). You must have the same version of Visual Studio used to compile
++your installation of Python, that is::
++
++* Python 2.6:  VS 2008
++* Python 2.7:  VS 2008
++* Python 3.3, 3.4: VS 2010 (you can download it from `MS website <http://www.visualstudio.com/downloads/download-visual-studio-vs#d-2010-express>`_)
++* Python 3.5: `VS 2015 UP <http://www.visualstudio.com/en-au/news/vs2015-preview-vs>`_
++
++...then run::
++
++    setup.py build
++
++...or::
++
++    make.bat build
++
++Compiling 64 bit versions of Python 2.6 and 2.7 with VS 2008 requires
++Windows SDK and .NET Framework 3.5 SP1 to be installed first.
++Once you have those run vcvars64.bat, then compile:
++http://stackoverflow.com/questions/11072521/
++
++===================
++Installing on Linux
++===================
++
++gcc is required and so the python headers. They can easily be installed by
++using the distro package manager. For example, on Debian amd Ubuntu::
++
++    $ sudo apt-get install gcc python-dev
++
++...on Redhat and CentOS::
++
++    $ sudo yum install gcc python-devel
++
++Once done, you can build/install psutil with::
++
++    $ python setup.py install
++
++
++==================
++Installing on OS X
++==================
++
++OS X installation from source will require gcc which you can obtain as part of
++the 'XcodeTools' installer from Apple. Then you can run the standard distutils
++commands.
++To build only::
++
++    $ python setup.py build
++
++To install and build::
++
++    $ python setup.py install
++
++
++=====================
++Installing on FreeBSD
++=====================
++
++The same compiler used to install Python must be present on the system in order
++to build modules using distutils. Assuming it is installed, you can build using
++the standard distutils commands.
++
++Build only::
++
++    $ python setup.py build
++
++Install and build::
++
++    $ python setup.py install
++
++
++========
++Makefile
++========
++
++A makefile is available for both UNIX and Windows (make.bat).  It provides
++some automations for the tasks described above and might be preferred over
++using setup.py. With it you can::
++
++    $ make install    # just install (in --user mode)
++    $ make uninstall  # uninstall (needs pip)
++    $ make test       # run tests
++    $ make clean      # remove installation files
+--- mozjs-24.2.0/js/src/python/psutil/make.bat	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/make.bat	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,233 @@
++@echo off
++
++rem ==========================================================================
++rem Shortcuts for various tasks, emulating UNIX "make" on Windows.
++rem It is primarly intended as a shortcut for compiling / installing
++rem psutil ("make.bat build", "make.bat install") and running tests
++rem ("make.bat test").
++rem
++rem This script is modeled after my Windows installation which uses:
++rem - Visual studio 2008 for Python 2.6, 2.7, 3.2
++rem - Visual studio 2010 for Python 3.3+
++rem ...therefore it might not work on your Windows installation.
++rem
++rem By default C:\Python27\python.exe is used.
++rem To compile for a specific Python version run:
++rem     set PYTHON=C:\Python34\python.exe & make.bat build
++rem
++rem To use a different test script:
++rem      set PYTHON=C:\Python34\python.exe & set TSCRIPT=foo.py & make.bat test
++rem ==========================================================================
++
++if "%PYTHON%" == "" (
++    set PYTHON=C:\Python27\python.exe
++)
++if "%TSCRIPT%" == "" (
++    set TSCRIPT=test\test_psutil.py
++)
++
++rem Needed to compile using Mingw.
++set PATH=C:\MinGW\bin;%PATH%
++
++rem Needed to locate the .pypirc file and upload exes on PYPI.
++set HOME=%USERPROFILE%
++
++rem ==========================================================================
++
++if "%1" == "help" (
++    :help
++    echo Run `make ^<target^>` where ^<target^> is one of:
++    echo   build         compile without installing
++    echo   build-exes    create exe installers in dist directory
++    echo   build-wheels  create wheel installers in dist directory
++    echo   build-all     build exes + wheels
++    echo   clean         clean build files
++    echo   install       compile and install
++    echo   setup-env     install pip, unittest2, wheels for all python versions
++    echo   test          run tests
++    echo   test-memleaks run memory leak tests
++    echo   test-process  run process related tests
++    echo   test-system   run system APIs related tests
++    echo   uninstall     uninstall
++    echo   upload-exes   upload exe installers on pypi
++    echo   upload-wheels upload wheel installers on pypi
++    echo   upload-all    upload exes + wheels
++    goto :eof
++)
++
++if "%1" == "clean" (
++    for /r %%R in (__pycache__) do if exist %%R (rmdir /S /Q %%R)
++    for /r %%R in (*.pyc) do if exist %%R (del /s %%R)
++    for /r %%R in (*.pyd) do if exist %%R (del /s %%R)
++    for /r %%R in (*.orig) do if exist %%R (del /s %%R)
++    for /r %%R in (*.bak) do if exist %%R (del /s %%R)
++    for /r %%R in (*.rej) do if exist %%R (del /s %%R)
++    if exist psutil.egg-info (rmdir /S /Q psutil.egg-info)
++    if exist build (rmdir /S /Q build)
++    if exist dist (rmdir /S /Q dist)
++    goto :eof
++)
++
++if "%1" == "build" (
++    :build
++    %PYTHON% setup.py build
++    if %errorlevel% neq 0 goto :error
++	rem copies *.pyd files in ./psutil directory in order to allow
++	rem "import psutil" when using the interactive interpreter from 
++    rem within this directory.
++    %PYTHON% setup.py build_ext -i
++    if %errorlevel% neq 0 goto :error
++    goto :eof
++)
++
++if "%1" == "install" (
++    :install
++    call :build
++    %PYTHON% setup.py install
++    goto :eof
++)
++
++if "%1" == "uninstall" (
++    for %%A in ("%PYTHON%") do (
++        set folder=%%~dpA
++    )
++    for /F "delims=" %%i in ('dir /b %folder%\Lib\site-packages\*psutil*') do (
++        rmdir /S /Q %folder%\Lib\site-packages\%%i
++    )
++    goto :eof
++)
++
++if "%1" == "test" (
++    call :install
++    %PYTHON% %TSCRIPT%
++    goto :eof
++)
++
++if "%1" == "test-process" (
++    call :install
++    %PYTHON% -m unittest -v test.test_psutil.TestProcess
++    goto :eof
++)
++
++if "%1" == "test-system" (
++    call :install
++    %PYTHON% -m unittest -v test.test_psutil.TestSystem
++    goto :eof
++)
++
++if "%1" == "test-memleaks" (
++    call :install
++    %PYTHON% test\test_memory_leaks.py
++    goto :eof
++)
++
++if "%1" == "build-exes" (
++    :build-exes
++    rem "standard" 32 bit versions, using VS 2008 (2.6, 2.7) or VS 2010 (3.3+)
++    C:\Python26\python.exe setup.py build bdist_wininst || goto :error
++    C:\Python27\python.exe setup.py build bdist_wininst || goto :error
++    C:\Python33\python.exe setup.py build bdist_wininst || goto :error
++    C:\Python34\python.exe setup.py build bdist_wininst || goto :error
++    rem 64 bit versions
++    rem Python 2.7 + VS 2008 requires vcvars64.bat to be run first:
++    rem http://stackoverflow.com/questions/11072521/
++    rem Windows SDK and .NET Framework 3.5 SP1 also need to be installed (sigh)
++    "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
++    C:\Python27-64\python.exe setup.py build bdist_wininst || goto :error
++    C:\Python33-64\python.exe setup.py build bdist_wininst || goto :error
++    C:\Python34-64\python.exe setup.py build bdist_wininst || goto :error
++    echo OK
++    goto :eof
++)
++
++if "%1" == "build-wheels" (
++    :build-wheels
++    C:\Python26\python.exe setup.py build bdist_wheel || goto :error
++    C:\Python27\python.exe setup.py build bdist_wheel || goto :error
++    C:\Python33\python.exe setup.py build bdist_wheel || goto :error
++    C:\Python34\python.exe setup.py build bdist_wheel || goto :error
++    rem 64 bit versions
++    rem Python 2.7 + VS 2008 requires vcvars64.bat to be run first:
++    rem http://stackoverflow.com/questions/11072521/
++    rem Windows SDK and .NET Framework 3.5 SP1 also need to be installed (sigh)
++    "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
++    C:\Python27-64\python.exe setup.py build bdist_wheel || goto :error
++    C:\Python33-64\python.exe setup.py build bdist_wheel || goto :error
++    C:\Python34-64\python.exe setup.py build bdist_wheel || goto :error
++    echo OK
++    goto :eof
++)
++
++if "%1" == "build-all" (
++    rem for some reason this needs to be called twice (f**king windows...)
++    call :build-exes
++    call :build-exes
++    echo OK
++    goto :eof
++)
++
++if "%1" == "upload-exes" (
++    :upload-exes
++    rem "standard" 32 bit versions, using VS 2008 (2.6, 2.7) or VS 2010 (3.3+)
++    C:\Python26\python.exe setup.py bdist_wininst upload || goto :error
++    C:\Python27\python.exe setup.py bdist_wininst upload || goto :error
++    C:\Python33\python.exe setup.py bdist_wininst upload || goto :error
++    C:\Python34\python.exe setup.py bdist_wininst upload || goto :error
++    rem 64 bit versions
++    C:\Python27-64\python.exe setup.py build bdist_wininst upload || goto :error
++    C:\Python33-64\python.exe setup.py build bdist_wininst upload || goto :error
++    C:\Python34-64\python.exe setup.py build bdist_wininst upload || goto :error
++    echo OK
++    goto :eof
++)
++
++if "%1" == "upload-wheels" (
++    :build-wheels
++    C:\Python26\python.exe setup.py build bdist_wheel upload || goto :error
++    C:\Python27\python.exe setup.py build bdist_wheel upload || goto :error
++    C:\Python33\python.exe setup.py build bdist_wheel upload || goto :error
++    C:\Python34\python.exe setup.py build bdist_wheel upload || goto :error
++    rem 64 bit versions
++    rem Python 2.7 + VS 2008 requires vcvars64.bat to be run first:
++    rem http://stackoverflow.com/questions/11072521/
++    rem Windows SDK and .NET Framework 3.5 SP1 also need to be installed (sigh)
++    "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
++    C:\Python27-64\python.exe setup.py build bdist_wheel upload || goto :error
++    C:\Python33-64\python.exe setup.py build bdist_wheel upload || goto :error
++    C:\Python34-64\python.exe setup.py build bdist_wheel upload || goto :error
++    echo OK
++    goto :eof
++)
++
++if "%1" == "upload-all" (
++    call :upload-exes
++    call :upload-wheels
++    echo OK
++    goto :eof
++)
++
++if "%1" == "setup-env" (
++    echo downloading pip installer
++    C:\python27\python.exe -c "import urllib2; url = urllib2.urlopen('https://raw.github.com/pypa/pip/master/contrib/get-pip.py'); data = url.read(); f = open('get-pip.py', 'w'); f.write(data)"
++    C:\python26\python.exe get-pip.py & C:\python26\scripts\pip install unittest2 wheel ipaddress --upgrade
++    C:\python27\python.exe get-pip.py & C:\python27\scripts\pip install wheel ipaddress --upgrade
++    C:\python33\python.exe get-pip.py & C:\python33\scripts\pip install wheel ipaddress --upgrade
++    C:\python34\scripts\easy_install.exe wheel
++    rem 64-bit versions
++    C:\python27-64\python.exe get-pip.py & C:\python27-64\scripts\pip install wheel ipaddress --upgrade
++    C:\python33-64\python.exe get-pip.py & C:\python33-64\scripts\pip install wheel ipaddress --upgrade
++    C:\python34-64\scripts\easy_install.exe wheel
++    rem install ipdb only for py 2.7 and 3.4
++    C:\python27\scripts\pip install ipdb --upgrade
++    C:\python34\scripts\easy_install.exe ipdb
++    goto :eof
++)
++
++goto :help
++
++:error
++    echo ------------------------------------------------
++    echo last command exited with error code %errorlevel%
++    echo ------------------------------------------------
++    exit /b %errorlevel%
++    goto :eof
+--- mozjs-24.2.0/js/src/python/psutil/Makefile	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/Makefile	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,126 @@
++# Shortcuts for various tasks (UNIX only).
++# To use a specific Python version run:
++# $ make install PYTHON=python3.3
++
++# You can set these variables from the command line.
++PYTHON    = python
++TSCRIPT   = test/test_psutil.py
++
++# Private vars
++COVERAGE_OPTS = --include="*psutil*" --omit="test/*,*setup*"
++
++all: test
++
++clean:
++	rm -f `find . -type f -name \*.py[co]`
++	rm -f `find . -type f -name \*.so`
++	rm -f `find . -type f -name .\*~`
++	rm -f `find . -type f -name \*.orig`
++	rm -f `find . -type f -name \*.bak`
++	rm -f `find . -type f -name \*.rej`
++	rm -rf `find . -type d -name __pycache__`
++	rm -rf *.core
++	rm -rf *.egg-info
++	rm -rf *\$testfile*
++	rm -rf .coverage
++	rm -rf .tox
++	rm -rf build
++	rm -rf dist
++	rm -rf docs/_build
++	rm -rf htmlcov
++
++build: clean
++	$(PYTHON) setup.py build
++	@# copies *.so files in ./psutil directory in order to allow
++	@# "import psutil" when using the interactive interpreter from within
++	@# this directory.
++	$(PYTHON) setup.py build_ext -i
++
++# useful deps which are nice to have while developing / testing
++install-dev-deps:
++	python -c "import urllib2; \
++			   r = urllib2.urlopen('https://bootstrap.pypa.io/get-pip.py'); \
++			   open('/tmp/get-pip.py', 'w').write(r.read());"
++	$(PYTHON) /tmp/get-pip.py --user
++	rm /tmp/get-pip.py
++	$(PYTHON) -m pip install --user --upgrade pip
++	$(PYTHON) -m pip install --user --upgrade \
++		# mandatory for unittests
++		ipaddress \
++		mock \
++		unittest2 \
++		# nice to have
++		coverage \
++		flake8 \
++		ipdb \
++		nose \
++		pep8 \
++		pyflakes \
++		sphinx \
++		sphinx-pypi-upload \
++
++install: build
++	$(PYTHON) setup.py install --user; \
++
++uninstall:
++	cd ..; $(PYTHON) -m pip uninstall -y -v psutil; \
++
++test: install
++	$(PYTHON) $(TSCRIPT)
++
++test-process: install
++	$(PYTHON) -m unittest -v test.test_psutil.TestProcess
++
++test-system: install
++	$(PYTHON) -m unittest -v test.test_psutil.TestSystemAPIs
++
++test-memleaks: install
++	$(PYTHON) test/test_memory_leaks.py
++
++# Run a specific test by name; e.g. "make test-by-name disk_" will run
++# all test methods containing "disk_" in their name.
++# Requires "pip install nose".
++test-by-name: install
++	@$(PYTHON) -m nose test/test_psutil.py --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS))
++
++# Same as above but for test_memory_leaks.py script.
++test-memleaks-by-name: install
++	@$(PYTHON) -m nose test/test_memory_leaks.py --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS))
++
++coverage: install
++	rm -rf .coverage htmlcov
++	$(PYTHON) -m coverage run $(TSCRIPT) $(COVERAGE_OPTS)
++	$(PYTHON) -m coverage report $(COVERAGE_OPTS)
++	@echo "writing results to htmlcov/index.html"
++	$(PYTHON) -m coverage html $(COVERAGE_OPTS)
++	$(PYTHON) -m webbrowser -t htmlcov/index.html
++
++pep8:
++	@git ls-files | grep \\.py$ | xargs $(PYTHON) -m pep8
++
++pyflakes:
++	@export PYFLAKES_NODOCTEST=1 && \
++		git ls-files | grep \\.py$ | xargs $(PYTHON) -m pyflakes
++
++flake8:
++	@git ls-files | grep \\.py$ | xargs $(PYTHON) -m flake8
++
++# Upload source tarball on https://pypi.python.org/pypi/psutil.
++upload-src: clean
++	$(PYTHON) setup.py sdist upload
++
++# Build and upload doc on https://pythonhosted.org/psutil/.
++# Requires "pip install sphinx-pypi-upload".
++upload-doc:
++	cd docs; make html
++	$(PYTHON) setup.py upload_sphinx --upload-dir=docs/_build/html
++
++# git-tag a new release
++git-tag-release:
++	git tag -a release-`python -c "import setup; print(setup.get_version())"` -m `git rev-list HEAD --count`:`git rev-parse --short HEAD`
++	echo "done; now run 'git push --follow-tags' to push the new tag on the remote repo"
++
++# install GIT pre-commit hook
++install-git-hooks:
++	ln -sf ../../.git-pre-commit .git/hooks/pre-commit
++	chmod +x .git/hooks/pre-commit
+--- mozjs-24.2.0/js/src/python/psutil/MANIFEST.in	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/MANIFEST.in	2015-06-17 19:33:33.000000000 -0700
+@@ -1,9 +1,20 @@
++include .git-pre-commit
++include .gitignore
++include .travis.yml
++include .git-pre-commit
+ include CREDITS
+-include HISTORY
++include HISTORY.rst
++include INSTALL.rst
+ include LICENSE
++include make.bat
++include Makefile
+ include MANIFEST.in
+-include README
++include README.rst
+ include setup.py
+-recursive-include psutil *.py *.c *.h
+-recursive-include test *.py
++include TODO
++include tox.ini
++recursive-include docs *
++recursive-exclude docs/_build *
+ recursive-include examples *.py
++recursive-include psutil *.py *.c *.h
++recursive-include test *.py README*
+--- mozjs-24.2.0/js/src/python/psutil/PKG-INFO	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/PKG-INFO	1969-12-31 16:00:00.000000000 -0800
+@@ -1,253 +0,0 @@
+-Metadata-Version: 1.1
+-Name: psutil
+-Version: 0.7.1
+-Summary: A process and system utilities module for Python
+-Home-page: http://code.google.com/p/psutil/
+-Author: Giampaolo Rodola
+-Author-email: g.rodola <at> gmail <dot> com
+-License: License :: OSI Approved :: BSD License
+-Download-URL: http://psutil.googlecode.com/files/psutil-0.7.1.tar.gz
+-Description: ===========
+-        Quick links
+-        ===========
+-        
+-        * `Home page <http://code.google.com/p/psutil>`_
+-        * `Download <http://code.google.com/p/psutil/downloads/list>`_
+-        * `Documentation <http://code.google.com/p/psutil/wiki/Documentation>`_
+-        
+-        =======
+-        Summary
+-        =======
+-        
+-        psutil is a module providing an interface for retrieving information on all
+-        running processes and system utilization (CPU, memory, disks, network, users) in
+-        a portable way by using Python, implementing many functionalities offered by
+-        command line tools such as:  **ps, top, df, kill, free, lsof, free, netstat,
+-        ifconfig, nice, ionice, iostat, iotop, uptime, pidof, tty, who, taskset, pmap**.
+-        
+-        It currently supports **Linux**, **Windows**, **OSX** and **FreeBSD** both
+-        **32-bit** and **64-bit** with Python versions from **2.4** to **3.3** by using
+-        a single code base.
+-        
+-        ==============
+-        Example usages
+-        ==============
+-        
+-        CPU
+-        ===
+-        
+-        >>> import psutil
+-        >>> psutil.cpu_times()
+-        cputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540,
+-                 iowait=629.509, irq=0.0, softirq=19.422)
+-        >>>
+-        >>> for x in range(3):
+-        ...     psutil.cpu_percent(interval=1)
+-        ...
+-        4.0
+-        5.9
+-        3.8
+-        >>>
+-        >>> for x in range(3):
+-        ...     psutil.cpu_percent(interval=1, percpu=True)
+-        ...
+-        [4.0, 6.9]
+-        [7.0, 8.5]
+-        [1.2, 9.0]
+-        >>>
+-        
+-        
+-        Memory
+-        ======
+-        
+-        >>> psutil.virtual_memory()
+-        vmem(total=8374149120L, available=2081050624L, percent=75.1, used=8074080256L,
+-             free=300068864L, active=3294920704, inactive=1361616896, buffers=529895424L,
+-             cached=1251086336)
+-        >>> psutil.swap_memory()
+-        swap(total=2097147904L, used=296128512L, free=1801019392L, percent=14.1,
+-             sin=304193536, sout=677842944)
+-        >>>
+-        
+-        
+-        Disks
+-        =====
+-        
+-        >>> psutil.disk_partitions()
+-        [partition(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
+-         partition(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
+-        >>>
+-        >>> psutil.disk_usage('/')
+-        usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
+-        >>>
+-        >>> psutil.disk_io_counters()
+-        iostat(read_count=719566, write_count=1082197, read_bytes=18626220032,
+-               write_bytes=24081764352, read_time=5023392, write_time=63199568)
+-        >>>
+-        
+-        
+-        Network
+-        =======
+-        
+-        >>> psutil.network_io_counters(pernic=True)
+-        {'lo': iostat(bytes_sent=799953745, bytes_recv=799953745,
+-                      packets_sent=453698, packets_recv=453698),
+-         'eth0': iostat(bytes_sent=734324837, bytes_recv=4163935363,
+-                        packets_sent=3605828, packets_recv=4096685)}
+-        >>>
+-        
+-        
+-        Users
+-        =====
+-        
+-        >>> psutil.get_users()
+-        [user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
+-         user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
+-        >>>
+-        
+-        
+-        Process management
+-        ==================
+-        
+-        >>> import psutil
+-        >>> psutil.get_pid_list()
+-        [1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,
+-        268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,
+-        2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245,
+-        4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358,
+-        4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
+-        5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
+-        >>>
+-        >>> p = psutil.Process(7055)
+-        >>> p.name
+-        'python'
+-        >>> p.exe
+-        '/usr/bin/python'
+-        >>> p.getcwd()
+-        '/home/giampaolo'
+-        >>> p.cmdline
+-        ['/usr/bin/python', 'main.py']
+-        >>>
+-        >>> str(p.status)
+-        'running'
+-        >>> p.username
+-        'giampaolo'
+-        >>> p.create_time
+-        1267551141.5019531
+-        >>> p.terminal
+-        '/dev/pts/0'
+-        >>>
+-        >>> p.uids
+-        user(real=1000, effective=1000, saved=1000)
+-        >>> p.gids
+-        group(real=1000, effective=1000, saved=1000)
+-        >>>
+-        >>> p.get_cpu_times()
+-        cputimes(user=1.02, system=0.31)
+-        >>> p.get_cpu_percent(interval=1.0)
+-        12.1
+-        >>> p.get_cpu_affinity()
+-        [0, 1, 2, 3]
+-        >>> p.set_cpu_affinity([0])
+-        >>>
+-        >>> p.get_memory_percent()
+-        0.63423
+-        >>>
+-        >>> p.get_memory_info()
+-        meminfo(rss=7471104, vms=68513792)
+-        >>> p.get_ext_memory_info()
+-        meminfo(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0)
+-        >>> p.get_memory_maps()
+-        [mmap(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
+-         mmap(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
+-         mmap(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0),
+-         mmap(path='[heap]', rss=54653, anonymous=8192, swap=0),
+-         mmap(path='[stack]', rss=1542, anonymous=166, swap=0),
+-         ...]
+-        >>>
+-        >>> p.get_io_counters()
+-        io(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632)
+-        >>>
+-        >>> p.get_open_files()
+-        [openfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)]
+-        >>>
+-        >>> p.get_connections()
+-        [connection(fd=115, family=2, type=1, local_address=('10.0.0.1', 48776),
+-                    remote_address=('93.186.135.91', 80), status='ESTABLISHED'),
+-         connection(fd=117, family=2, type=1, local_address=('10.0.0.1', 43761),
+-                    remote_address=('72.14.234.100', 80), status='CLOSING'),
+-         connection(fd=119, family=2, type=1, local_address=('10.0.0.1', 60759),
+-                    remote_address=('72.14.234.104', 80), status='ESTABLISHED'),
+-         connection(fd=123, family=2, type=1, local_address=('10.0.0.1', 51314),
+-                    remote_address=('72.14.234.83', 443), status='SYN_SENT')]
+-        >>>
+-        >>> p.get_num_threads()
+-        4
+-        >>> p.get_num_fds()
+-        8
+-        >>> p.get_threads()
+-        [thread(id=5234, user_time=22.5, system_time=9.2891),
+-         thread(id=5235, user_time=0.0, system_time=0.0),
+-         thread(id=5236, user_time=0.0, system_time=0.0),
+-         thread(id=5237, user_time=0.0707, system_time=1.1)]
+-        >>>
+-        >>> p.get_num_ctx_switches()
+-        amount(voluntary=78, involuntary=19)
+-        >>>
+-        >>> p.get_nice()
+-        0
+-        >>> p.set_nice(10)
+-        >>>
+-        >>> p.suspend()
+-        >>> p.resume()
+-        >>>
+-        >>> p.terminate()
+-        >>> p.wait(timeout=3)
+-        0
+-        >>>
+-        >>> psutil.test()
+-        USER         PID %CPU %MEM     VSZ     RSS TTY        START    TIME  COMMAND
+-        root           1  0.0  0.0   24584    2240 ?          Jun17   00:00  init
+-        root           2  0.0  0.0       0       0 ?          Jun17   00:00  kthreadd
+-        root           3  0.0  0.0       0       0 ?          Jun17   00:05  ksoftirqd/0
+-        ...
+-        giampaolo  31475  0.0  0.0   20760    3024 /dev/pts/0 Jun19   00:00  python2.4
+-        giampaolo  31721  0.0  2.2  773060  181896 ?          00:04   10:30  chrome
+-        root       31763  0.0  0.0       0       0 ?          00:05   00:00  kworker/0:1
+-        >>>
+-        
+-Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,monitoring
+-Platform: Platform Independent
+-Classifier: Development Status :: 5 - Production/Stable
+-Classifier: Environment :: Console
+-Classifier: Operating System :: MacOS :: MacOS X
+-Classifier: Operating System :: Microsoft
+-Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
+-Classifier: Operating System :: POSIX
+-Classifier: Operating System :: POSIX :: Linux
+-Classifier: Operating System :: POSIX :: BSD :: FreeBSD
+-Classifier: Operating System :: OS Independent
+-Classifier: Programming Language :: C
+-Classifier: Programming Language :: Python
+-Classifier: Programming Language :: Python :: 2
+-Classifier: Programming Language :: Python :: 2.4
+-Classifier: Programming Language :: Python :: 2.5
+-Classifier: Programming Language :: Python :: 2.6
+-Classifier: Programming Language :: Python :: 2.7
+-Classifier: Programming Language :: Python :: 3
+-Classifier: Programming Language :: Python :: 3.0
+-Classifier: Programming Language :: Python :: 3.1
+-Classifier: Programming Language :: Python :: 3.2
+-Classifier: Programming Language :: Python :: 3.3
+-Classifier: Topic :: System :: Monitoring
+-Classifier: Topic :: System :: Networking
+-Classifier: Topic :: System :: Networking :: Monitoring
+-Classifier: Topic :: System :: Benchmark
+-Classifier: Topic :: System :: Hardware
+-Classifier: Topic :: System :: Systems Administration
+-Classifier: Topic :: Utilities
+-Classifier: Topic :: Software Development :: Libraries
+-Classifier: Topic :: Software Development :: Libraries :: Python Modules
+-Classifier: Intended Audience :: Developers
+-Classifier: Intended Audience :: System Administrators
+-Classifier: License :: OSI Approved :: BSD License
+--- mozjs-24.2.0/js/src/python/psutil/psutil/__init__.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/__init__.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,170 +1,391 @@
+ #!/usr/bin/env python
+ # -*- coding: utf-8 -*-
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+-"""psutil is a module providing convenience functions for managing
+-processes and gather system information in a portable way by using
+-Python.
++"""psutil is a cross-platform library for retrieving information on
++running processes and system utilization (CPU, memory, disks, network)
++in Python.
+ """
+ 
+ from __future__ import division
+ 
+-__version__ = "0.7.1"
+-version_info = tuple([int(num) for num in __version__.split('.')])
+-
+-__all__ = [
+-    # exceptions
+-    "Error", "NoSuchProcess", "AccessDenied", "TimeoutExpired",
+-    # constants
+-    "NUM_CPUS", "TOTAL_PHYMEM", "BOOT_TIME",
+-    "version_info", "__version__",
+-    "STATUS_RUNNING", "STATUS_IDLE", "STATUS_SLEEPING", "STATUS_DISK_SLEEP",
+-    "STATUS_STOPPED", "STATUS_TRACING_STOP", "STATUS_ZOMBIE", "STATUS_DEAD",
+-    "STATUS_WAKING", "STATUS_LOCKED",
+-    # classes
+-    "Process", "Popen",
+-    # functions
+-    "pid_exists", "get_pid_list", "process_iter",                   # proc
+-    "virtual_memory", "swap_memory",                                # memory
+-    "cpu_times", "cpu_percent", "cpu_times_percent",                # cpu
+-    "network_io_counters",                                          # network
+-    "disk_io_counters", "disk_partitions", "disk_usage",            # disk
+-    "get_users", "get_boot_time",                                   # others
+-    ]
+-
+-import sys
++import collections
++import errno
++import functools
+ import os
+-import time
+ import signal
+-import warnings
+-import errno
+ import subprocess
++import sys
++import time
+ try:
+     import pwd
+ except ImportError:
+     pwd = None
+ 
+-from psutil._error import Error, NoSuchProcess, AccessDenied, TimeoutExpired
+-from psutil._common import cached_property
+-from psutil._compat import (property, callable, defaultdict, namedtuple,
+-                            wraps as _wraps, PY3 as _PY3)
+-from psutil._common import (deprecated as _deprecated,
+-                            nt_disk_iostat as _nt_disk_iostat,
+-                            nt_net_iostat as _nt_net_iostat,
+-                            nt_sysmeminfo as _nt_sysmeminfo,
+-                            isfile_strict as _isfile_strict)
+-from psutil._common import (STATUS_RUNNING, STATUS_IDLE, STATUS_SLEEPING,
+-                            STATUS_DISK_SLEEP, STATUS_STOPPED,
+-                            STATUS_TRACING_STOP, STATUS_ZOMBIE, STATUS_DEAD,
+-                            STATUS_WAKING, STATUS_LOCKED)
++from . import _common
++from ._common import memoize
++from ._compat import callable, long
++from ._compat import PY3 as _PY3
++
++from ._common import (STATUS_RUNNING,  # NOQA
++                      STATUS_SLEEPING,
++                      STATUS_DISK_SLEEP,
++                      STATUS_STOPPED,
++                      STATUS_TRACING_STOP,
++                      STATUS_ZOMBIE,
++                      STATUS_DEAD,
++                      STATUS_WAKING,
++                      STATUS_LOCKED,
++                      STATUS_IDLE,  # bsd
++                      STATUS_WAITING)  # bsd
++
++from ._common import (CONN_ESTABLISHED,
++                      CONN_SYN_SENT,
++                      CONN_SYN_RECV,
++                      CONN_FIN_WAIT1,
++                      CONN_FIN_WAIT2,
++                      CONN_TIME_WAIT,
++                      CONN_CLOSE,
++                      CONN_CLOSE_WAIT,
++                      CONN_LAST_ACK,
++                      CONN_LISTEN,
++                      CONN_CLOSING,
++                      CONN_NONE)
++
++from ._common import (NIC_DUPLEX_FULL,  # NOQA
++                      NIC_DUPLEX_HALF,
++                      NIC_DUPLEX_UNKNOWN)
+ 
+-# import the appropriate module for our platform only
+ if sys.platform.startswith("linux"):
+-    import psutil._pslinux as _psplatform
+-    from psutil._pslinux import (phymem_buffers,
+-                                 cached_phymem,
+-                                 IOPRIO_CLASS_NONE,
+-                                 IOPRIO_CLASS_RT,
+-                                 IOPRIO_CLASS_BE,
+-                                 IOPRIO_CLASS_IDLE)
+-    phymem_buffers = _psplatform.phymem_buffers
+-    cached_phymem = _psplatform.cached_phymem
++    from . import _pslinux as _psplatform
++
++    from ._pslinux import (IOPRIO_CLASS_NONE,  # NOQA
++                           IOPRIO_CLASS_RT,
++                           IOPRIO_CLASS_BE,
++                           IOPRIO_CLASS_IDLE)
++    # Linux >= 2.6.36
++    if _psplatform.HAS_PRLIMIT:
++        from ._psutil_linux import (RLIM_INFINITY,  # NOQA
++                                    RLIMIT_AS,
++                                    RLIMIT_CORE,
++                                    RLIMIT_CPU,
++                                    RLIMIT_DATA,
++                                    RLIMIT_FSIZE,
++                                    RLIMIT_LOCKS,
++                                    RLIMIT_MEMLOCK,
++                                    RLIMIT_NOFILE,
++                                    RLIMIT_NPROC,
++                                    RLIMIT_RSS,
++                                    RLIMIT_STACK)
++        # Kinda ugly but considerably faster than using hasattr() and
++        # setattr() against the module object (we are at import time:
++        # speed matters).
++        from . import _psutil_linux
++        try:
++            RLIMIT_MSGQUEUE = _psutil_linux.RLIMIT_MSGQUEUE
++        except AttributeError:
++            pass
++        try:
++            RLIMIT_NICE = _psutil_linux.RLIMIT_NICE
++        except AttributeError:
++            pass
++        try:
++            RLIMIT_RTPRIO = _psutil_linux.RLIMIT_RTPRIO
++        except AttributeError:
++            pass
++        try:
++            RLIMIT_RTTIME = _psutil_linux.RLIMIT_RTTIME
++        except AttributeError:
++            pass
++        try:
++            RLIMIT_SIGPENDING = _psutil_linux.RLIMIT_SIGPENDING
++        except AttributeError:
++            pass
++        del _psutil_linux
+ 
+ elif sys.platform.startswith("win32"):
+-    import psutil._psmswindows as _psplatform
+-    from psutil._psmswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
+-                                     BELOW_NORMAL_PRIORITY_CLASS,
+-                                     HIGH_PRIORITY_CLASS,
+-                                     IDLE_PRIORITY_CLASS,
+-                                     NORMAL_PRIORITY_CLASS,
+-                                     REALTIME_PRIORITY_CLASS)
++    from . import _pswindows as _psplatform
++    from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS,  # NOQA
++                                  BELOW_NORMAL_PRIORITY_CLASS,
++                                  HIGH_PRIORITY_CLASS,
++                                  IDLE_PRIORITY_CLASS,
++                                  NORMAL_PRIORITY_CLASS,
++                                  REALTIME_PRIORITY_CLASS)
++    from ._pswindows import CONN_DELETE_TCB  # NOQA
+ 
+ elif sys.platform.startswith("darwin"):
+-    import psutil._psosx as _psplatform
++    from . import _psosx as _psplatform
+ 
+ elif sys.platform.startswith("freebsd"):
+-    import psutil._psbsd as _psplatform
++    from . import _psbsd as _psplatform
++
++elif sys.platform.startswith("sunos"):
++    from . import _pssunos as _psplatform
++    from ._pssunos import (CONN_IDLE,  # NOQA
++                           CONN_BOUND)
+ 
+ else:
+     raise NotImplementedError('platform %s is not supported' % sys.platform)
+ 
++
++__all__ = [
++    # exceptions
++    "Error", "NoSuchProcess", "ZombieProcess", "AccessDenied",
++    "TimeoutExpired",
++    # constants
++    "version_info", "__version__",
++    "STATUS_RUNNING", "STATUS_IDLE", "STATUS_SLEEPING", "STATUS_DISK_SLEEP",
++    "STATUS_STOPPED", "STATUS_TRACING_STOP", "STATUS_ZOMBIE", "STATUS_DEAD",
++    "STATUS_WAKING", "STATUS_LOCKED", "STATUS_WAITING", "STATUS_LOCKED",
++    "CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1",
++    "CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
++    "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", "CONN_NONE",
++    "AF_LINK",
++    "NIC_DUPLEX_FULL", "NIC_DUPLEX_HALF", "NIC_DUPLEX_UNKNOWN",
++    # classes
++    "Process", "Popen",
++    # functions
++    "pid_exists", "pids", "process_iter", "wait_procs",             # proc
++    "virtual_memory", "swap_memory",                                # memory
++    "cpu_times", "cpu_percent", "cpu_times_percent", "cpu_count",   # cpu
++    "net_io_counters", "net_connections", "net_if_addrs",           # network
++    "net_if_stats",
++    "disk_io_counters", "disk_partitions", "disk_usage",            # disk
++    "users", "boot_time",                                           # others
++]
+ __all__.extend(_psplatform.__extra__all__)
++__author__ = "Giampaolo Rodola'"
++__version__ = "3.0.1"
++version_info = tuple([int(num) for num in __version__.split('.')])
++AF_LINK = _psplatform.AF_LINK
++_TOTAL_PHYMEM = None
++_POSIX = os.name == 'posix'
++_WINDOWS = os.name == 'nt'
++_timer = getattr(time, 'monotonic', time.time)
++
++
++# Sanity check in case the user messed up with psutil installation
++# or did something weird with sys.path. In this case we might end
++# up importing a python module using a C extension module which
++# was compiled for a different version of psutil.
++# We want to prevent that by failing sooner rather than later.
++# See: https://github.com/giampaolo/psutil/issues/564
++if (int(__version__.replace('.', '')) !=
++        getattr(_psplatform.cext, 'version', None)):
++    msg = "version conflict: %r C extension module was built for another " \
++          "version of psutil (different than %s)" % (_psplatform.cext.__file__,
++                                                     __version__)
++    raise ImportError(msg)
++
++
++# =====================================================================
++# --- exceptions
++# =====================================================================
++
++class Error(Exception):
++    """Base exception class. All other psutil exceptions inherit
++    from this one.
++    """
+ 
+-NUM_CPUS = _psplatform.NUM_CPUS
+-BOOT_TIME = _psplatform.BOOT_TIME
+-TOTAL_PHYMEM = _psplatform.TOTAL_PHYMEM
++    def __init__(self, msg=""):
++        self.msg = msg
++
++    def __str__(self):
++        return self.msg
++
++
++class NoSuchProcess(Error):
++    """Exception raised when a process with a certain PID doesn't
++    or no longer exists.
++    """
++
++    def __init__(self, pid, name=None, msg=None):
++        Error.__init__(self, msg)
++        self.pid = pid
++        self.name = name
++        self.msg = msg
++        if msg is None:
++            if name:
++                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
++            else:
++                details = "(pid=%s)" % self.pid
++            self.msg = "process no longer exists " + details
++
++
++class ZombieProcess(NoSuchProcess):
++    """Exception raised when querying a zombie process. This is
++    raised on OSX, BSD and Solaris only, and not always: depending
++    on the query the OS may be able to succeed anyway.
++    On Linux all zombie processes are querable (hence this is never
++    raised). Windows doesn't have zombie processes.
++    """
++
++    def __init__(self, pid, name=None, ppid=None, msg=None):
++        Error.__init__(self, msg)
++        self.pid = pid
++        self.ppid = ppid
++        self.name = name
++        self.msg = msg
++        if msg is None:
++            if name and ppid:
++                details = "(pid=%s, name=%s, ppid=%s)" % (
++                    self.pid, repr(self.name), self.ppid)
++            elif name:
++                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
++            else:
++                details = "(pid=%s)" % self.pid
++            self.msg = "process still exists but it's a zombie " + details
++
++
++class AccessDenied(Error):
++    """Exception raised when permission to perform an action is denied."""
++
++    def __init__(self, pid=None, name=None, msg=None):
++        Error.__init__(self, msg)
++        self.pid = pid
++        self.name = name
++        self.msg = msg
++        if msg is None:
++            if (pid is not None) and (name is not None):
++                self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
++            elif (pid is not None):
++                self.msg = "(pid=%s)" % self.pid
++            else:
++                self.msg = ""
++
++
++class TimeoutExpired(Error):
++    """Raised on Process.wait(timeout) if timeout expires and process
++    is still alive.
++    """
++
++    def __init__(self, seconds, pid=None, name=None):
++        Error.__init__(self, "timeout after %s seconds" % seconds)
++        self.seconds = seconds
++        self.pid = pid
++        self.name = name
++        if (pid is not None) and (name is not None):
++            self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
++        elif (pid is not None):
++            self.msg += " (pid=%s)" % self.pid
++
++
++# push exception classes into platform specific module namespace
++_psplatform.NoSuchProcess = NoSuchProcess
++_psplatform.ZombieProcess = ZombieProcess
++_psplatform.AccessDenied = AccessDenied
++_psplatform.TimeoutExpired = TimeoutExpired
++
++
++# =====================================================================
++# --- Process class
++# =====================================================================
+ 
+ 
+ def _assert_pid_not_reused(fun):
+     """Decorator which raises NoSuchProcess in case a process is no
+     longer running or its PID has been reused.
+     """
+-    @_wraps(fun)
++    @functools.wraps(fun)
+     def wrapper(self, *args, **kwargs):
+         if not self.is_running():
+-            raise NoSuchProcess(self.pid, self._platform_impl._process_name)
++            raise NoSuchProcess(self.pid, self._name)
+         return fun(self, *args, **kwargs)
+     return wrapper
+ 
+ 
+ class Process(object):
+-    """Represents an OS process."""
++    """Represents an OS process with the given PID.
++    If PID is omitted current process PID (os.getpid()) is used.
++    Raise NoSuchProcess if PID does not exist.
++
++    Note that most of the methods of this class do not make sure
++    the PID of the process being queried has been reused over time.
++    That means you might end up retrieving an information referring
++    to another process in case the original one this instance
++    refers to is gone in the meantime.
++
++    The only exceptions for which process identity is pre-emptively
++    checked and guaranteed are:
++
++     - parent()
++     - children()
++     - nice() (set)
++     - ionice() (set)
++     - rlimit() (set)
++     - cpu_affinity (set)
++     - suspend()
++     - resume()
++     - send_signal()
++     - terminate()
++     - kill()
++
++    To prevent this problem for all other methods you can:
++      - use is_running() before querying the process
++      - if you're continuously iterating over a set of Process
++        instances use process_iter() which pre-emptively checks
++        process identity for every yielded instance
++    """
++
++    def __init__(self, pid=None):
++        self._init(pid)
+ 
+-    def __init__(self, pid):
+-        """Create a new Process object for the given pid.
+-        Raises NoSuchProcess if pid does not exist.
+-
+-        Note that most of the methods of this class do not make sure
+-        the PID of the process being queried has been reused.
+-        That means you might end up retrieving an information referring
+-        to another process in case the original one this instance
+-        refers to is gone in the meantime.
+-
+-        The only exceptions for which process identity is pre-emptively
+-        checked are:
+-         - parent
+-         - get_children()
+-         - set_nice()
+-         - suspend()
+-         - resume()
+-         - send_signal()
+-         - terminate()
+-         - kill()
+-
+-        To prevent this problem for all other methods you can:
+-          - use is_running() before querying the process
+-          - if you're continuously iterating over a set of Process
+-            instances use process_iter() which pre-emptively checks
+-            process identity for every yielded instance
+-        """
+-        if not _PY3:
+-            if not isinstance(pid, (int, long)):
+-                raise TypeError('pid must be an integer')
+-        if pid < 0:
+-            raise ValueError('pid must be a positive integer')
++    def _init(self, pid, _ignore_nsp=False):
++        if pid is None:
++            pid = os.getpid()
++        else:
++            if not _PY3 and not isinstance(pid, (int, long)):
++                raise TypeError('pid must be an integer (got %r)' % pid)
++            if pid < 0:
++                raise ValueError('pid must be a positive integer (got %s)'
++                                 % pid)
+         self._pid = pid
++        self._name = None
++        self._exe = None
++        self._create_time = None
+         self._gone = False
++        self._hash = None
++        # used for caching on Windows only (on POSIX ppid may change)
+         self._ppid = None
+         # platform-specific modules define an _psplatform.Process
+         # implementation class
+-        self._platform_impl = _psplatform.Process(pid)
++        self._proc = _psplatform.Process(pid)
+         self._last_sys_cpu_times = None
+         self._last_proc_cpu_times = None
+         # cache creation time for later use in is_running() method
+         try:
+-            self.create_time
++            self.create_time()
+         except AccessDenied:
++            # we should never get here as AFAIK we're able to get
++            # process creation time on all platforms even as a
++            # limited user
++            pass
++        except ZombieProcess:
++            # Let's consider a zombie process as legitimate as
++            # tehcnically it's still alive (it can be queried,
++            # although not always, and it's returned by pids()).
+             pass
+         except NoSuchProcess:
+-            raise NoSuchProcess(pid, None, 'no process found with pid %s' % pid)
++            if not _ignore_nsp:
++                msg = 'no process found with pid %s' % pid
++                raise NoSuchProcess(pid, None, msg)
++            else:
++                self._gone = True
++        # This pair is supposed to indentify a Process instance
++        # univocally over time (the PID alone is not enough as
++        # it might refer to a process whose PID has been reused).
++        # This will be used later in __eq__() and is_running().
++        self._ident = (self.pid, self._create_time)
+ 
+     def __str__(self):
+         try:
+             pid = self.pid
+-            name = repr(self.name)
++            name = repr(self.name())
++        except ZombieProcess:
++            details = "(pid=%s (zombie))" % self.pid
+         except NoSuchProcess:
+             details = "(pid=%s (terminated))" % self.pid
+         except AccessDenied:
+@@ -177,41 +398,53 @@
+     def __repr__(self):
+         return "<%s at %s>" % (self.__str__(), id(self))
+ 
++    def __eq__(self, other):
++        # Test for equality with another Process object based
++        # on PID and creation time.
++        if not isinstance(other, Process):
++            return NotImplemented
++        return self._ident == other._ident
++
++    def __ne__(self, other):
++        return not self == other
++
++    def __hash__(self):
++        if self._hash is None:
++            self._hash = hash(self._ident)
++        return self._hash
++
+     # --- utility methods
+ 
+-    def as_dict(self, attrs=[], ad_value=None):
+-        """Utility method returning process information as a hashable
+-        dictionary.
+-
+-        If 'attrs' is specified it must be a list of strings reflecting
+-        available Process class's attribute names (e.g. ['get_cpu_times',
+-        'name']) else all public (read only) attributes are assumed.
+-
+-        'ad_value' is the value which gets assigned to a dict key in case
+-        AccessDenied exception is raised when retrieving that particular
+-        process information.
+-        """
+-        excluded_names = set(['send_signal', 'suspend', 'resume', 'terminate',
+-                              'kill', 'wait', 'is_running', 'as_dict', 'parent',
+-                              'get_children', 'nice'])
++    def as_dict(self, attrs=None, ad_value=None):
++        """Utility method returning process information as a
++        hashable dictionary.
++
++        If 'attrs' is specified it must be a list of strings
++        reflecting available Process class' attribute names
++        (e.g. ['cpu_times', 'name']) else all public (read
++        only) attributes are assumed.
++
++        'ad_value' is the value which gets assigned in case
++        AccessDenied or ZombieProcess exception is raised when
++        retrieving that particular process information.
++        """
++        excluded_names = set(
++            ['send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
++             'is_running', 'as_dict', 'parent', 'children', 'rlimit'])
+         retdict = dict()
+-        for name in set(attrs or dir(self)):
++        ls = set(attrs or [x for x in dir(self)])
++        for name in ls:
+             if name.startswith('_'):
+                 continue
+-            if name.startswith('set_'):
+-                continue
+             if name in excluded_names:
+                 continue
+             try:
+                 attr = getattr(self, name)
+                 if callable(attr):
+-                    if name == 'get_cpu_percent':
+-                        ret = attr(interval=0)
+-                    else:
+-                        ret = attr()
++                    ret = attr()
+                 else:
+                     ret = attr
+-            except AccessDenied:
++            except (AccessDenied, ZombieProcess):
+                 ret = ad_value
+             except NotImplementedError:
+                 # in case of not implemented functionality (may happen
+@@ -220,205 +453,222 @@
+                 if attrs:
+                     raise
+                 continue
+-            if name.startswith('get'):
+-                if name[3] == '_':
+-                    name = name[4:]
+-                elif name == 'getcwd':
+-                    name = 'cwd'
+             retdict[name] = ret
+         return retdict
+ 
+-    @property
+-    @_assert_pid_not_reused
+     def parent(self):
+         """Return the parent process as a Process object pre-emptively
+         checking whether PID has been reused.
+         If no parent is known return None.
+         """
+-        ppid = self.ppid
++        ppid = self.ppid()
+         if ppid is not None:
++            ctime = self.create_time()
+             try:
+                 parent = Process(ppid)
+-                if parent.create_time <= self.create_time:
++                if parent.create_time() <= ctime:
+                     return parent
+                 # ...else ppid has been reused by another process
+             except NoSuchProcess:
+                 pass
+ 
++    def is_running(self):
++        """Return whether this process is running.
++        It also checks if PID has been reused by another process in
++        which case return False.
++        """
++        if self._gone:
++            return False
++        try:
++            # Checking if PID is alive is not enough as the PID might
++            # have been reused by another process: we also want to
++            # check process identity.
++            # Process identity / uniqueness over time is greanted by
++            # (PID + creation time) and that is verified in __eq__.
++            return self == Process(self.pid)
++        except NoSuchProcess:
++            self._gone = True
++            return False
++
+     # --- actual API
+ 
+     @property
+     def pid(self):
+-        """The process pid."""
++        """The process PID."""
+         return self._pid
+ 
+-    @property
+     def ppid(self):
+-        """The process parent pid."""
++        """The process parent PID.
++        On Windows the return value is cached after first call.
++        """
+         # On POSIX we don't want to cache the ppid as it may unexpectedly
+         # change to 1 (init) in case this process turns into a zombie:
+-        # https://code.google.com/p/psutil/issues/detail?id=321
++        # https://github.com/giampaolo/psutil/issues/321
+         # http://stackoverflow.com/questions/356722/
+ 
+         # XXX should we check creation time here rather than in
+-        # Process.parent?
+-        if os.name == 'posix':
+-            return self._platform_impl.get_process_ppid()
++        # Process.parent()?
++        if _POSIX:
++            return self._proc.ppid()
+         else:
+-            if self._ppid is None:
+-                self._ppid = self._platform_impl.get_process_ppid()
++            self._ppid = self._ppid or self._proc.ppid()
+             return self._ppid
+ 
+-    @cached_property
+     def name(self):
+-        """The process name."""
+-        name = self._platform_impl.get_process_name()
+-        if os.name == 'posix':
+-            # On UNIX the name gets truncated to the first 15 characters.
+-            # If it matches the first part of the cmdline we return that
+-            # one instead because it's usually more explicative.
+-            # Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
+-            try:
+-                cmdline = self.cmdline
+-            except AccessDenied:
+-                pass
+-            else:
+-                if cmdline:
+-                    extended_name = os.path.basename(cmdline[0])
+-                    if extended_name.startswith(name):
+-                        name = extended_name
+-        # XXX - perhaps needs refactoring
+-        self._platform_impl._process_name = name
+-        return name
++        """The process name. The return value is cached after first call."""
++        if self._name is None:
++            name = self._proc.name()
++            if _POSIX and len(name) >= 15:
++                # On UNIX the name gets truncated to the first 15 characters.
++                # If it matches the first part of the cmdline we return that
++                # one instead because it's usually more explicative.
++                # Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
++                try:
++                    cmdline = self.cmdline()
++                except AccessDenied:
++                    pass
++                else:
++                    if cmdline:
++                        extended_name = os.path.basename(cmdline[0])
++                        if extended_name.startswith(name):
++                            name = extended_name
++            self._proc._name = name
++            self._name = name
++        return self._name
+ 
+-    @cached_property
+     def exe(self):
+-        """The process executable path. May also be an empty string."""
++        """The process executable as an absolute path.
++        May also be an empty string.
++        The return value is cached after first call.
++        """
+         def guess_it(fallback):
+             # try to guess exe from cmdline[0] in absence of a native
+             # exe representation
+-            cmdline = self.cmdline
++            cmdline = self.cmdline()
+             if cmdline and hasattr(os, 'access') and hasattr(os, 'X_OK'):
+                 exe = cmdline[0]  # the possible exe
+-                rexe = os.path.realpath(exe)  # ...in case it's a symlink
+-                if os.path.isabs(rexe) and os.path.isfile(rexe) \
+-                and os.access(rexe, os.X_OK):
++                # Attempt to guess only in case of an absolute path.
++                # It is not safe otherwise as the process might have
++                # changed cwd.
++                if (os.path.isabs(exe) and
++                        os.path.isfile(exe) and
++                        os.access(exe, os.X_OK)):
+                     return exe
+             if isinstance(fallback, AccessDenied):
+                 raise fallback
+             return fallback
+ 
+-        try:
+-            exe = self._platform_impl.get_process_exe()
+-        except AccessDenied:
+-            err = sys.exc_info()[1]
+-            return guess_it(fallback=err)
+-        else:
+-            if not exe:
+-                # underlying implementation can legitimately return an
+-                # empty string; if that's the case we don't want to
+-                # raise AD while guessing from the cmdline
+-                try:
+-                    exe = guess_it(fallback=exe)
+-                except AccessDenied:
+-                    pass
+-            return exe
++        if self._exe is None:
++            try:
++                exe = self._proc.exe()
++            except AccessDenied as err:
++                return guess_it(fallback=err)
++            else:
++                if not exe:
++                    # underlying implementation can legitimately return an
++                    # empty string; if that's the case we don't want to
++                    # raise AD while guessing from the cmdline
++                    try:
++                        exe = guess_it(fallback=exe)
++                    except AccessDenied:
++                        pass
++                self._exe = exe
++        return self._exe
+ 
+-    @property
+     def cmdline(self):
+-        """The command line process has been called with."""
+-        return self._platform_impl.get_process_cmdline()
++        """The command line this process has been called with."""
++        return self._proc.cmdline()
+ 
+-    @property
+     def status(self):
+         """The process current status as a STATUS_* constant."""
+-        return self._platform_impl.get_process_status()
+-
+-    if os.name == 'posix':
+-
+-        @property
+-        def uids(self):
+-            """Return a named tuple denoting the process real,
+-            effective, and saved user ids.
+-            """
+-            return self._platform_impl.get_process_uids()
+-
+-        @property
+-        def gids(self):
+-            """Return a named tuple denoting the process real,
+-            effective, and saved group ids.
+-            """
+-            return self._platform_impl.get_process_gids()
+-
+-        @property
+-        def terminal(self):
+-            """The terminal associated with this process, if any,
+-            else None.
+-            """
+-            return self._platform_impl.get_process_terminal()
++        try:
++            return self._proc.status()
++        except ZombieProcess:
++            return STATUS_ZOMBIE
+ 
+-    @property
+     def username(self):
+         """The name of the user that owns the process.
+         On UNIX this is calculated by using *real* process uid.
+         """
+-        if os.name == 'posix':
++        if _POSIX:
+             if pwd is None:
+                 # might happen if python was installed from sources
+-                raise ImportError("requires pwd module shipped with standard python")
+-            return pwd.getpwuid(self.uids.real).pw_name
++                raise ImportError(
++                    "requires pwd module shipped with standard python")
++            real_uid = self.uids().real
++            try:
++                return pwd.getpwuid(real_uid).pw_name
++            except KeyError:
++                # the uid can't be resolved by the system
++                return str(real_uid)
+         else:
+-            return self._platform_impl.get_process_username()
++            return self._proc.username()
+ 
+-    @cached_property
+     def create_time(self):
+         """The process creation time as a floating point number
+         expressed in seconds since the epoch, in UTC.
++        The return value is cached after first call.
+         """
+-        return self._platform_impl.get_process_create_time()
++        if self._create_time is None:
++            self._create_time = self._proc.create_time()
++        return self._create_time
++
++    def cwd(self):
++        """Process current working directory as an absolute path."""
++        return self._proc.cwd()
++
++    def nice(self, value=None):
++        """Get or set process niceness (priority)."""
++        if value is None:
++            return self._proc.nice_get()
++        else:
++            if not self.is_running():
++                raise NoSuchProcess(self.pid, self._name)
++            self._proc.nice_set(value)
+ 
+-    def getcwd(self):
+-        """Return a string representing the process current working
+-        directory.
+-        """
+-        return self._platform_impl.get_process_cwd()
++    if _POSIX:
+ 
+-    # Linux, BSD and Windows only
+-    if hasattr(_psplatform.Process, "get_process_io_counters"):
++        def uids(self):
++            """Return process UIDs as a (real, effective, saved)
++            namedtuple.
++            """
++            return self._proc.uids()
+ 
+-        def get_io_counters(self):
+-            """Return process I/O statistics as a namedtuple including
+-            the number of read/write calls performed and the amount of
+-            bytes read and written by the process.
++        def gids(self):
++            """Return process GIDs as a (real, effective, saved)
++            namedtuple.
+             """
+-            return self._platform_impl.get_process_io_counters()
++            return self._proc.gids()
+ 
+-    def get_nice(self):
+-        """Get process niceness (priority)."""
+-        return self._platform_impl.get_process_nice()
++        def terminal(self):
++            """The terminal associated with this process, if any,
++            else None.
++            """
++            return self._proc.terminal()
+ 
+-    @_assert_pid_not_reused
+-    def set_nice(self, value):
+-        """Set process niceness (priority) pre-emptively checking
+-        whether PID has been reused."""
+-        return self._platform_impl.set_process_nice(value)
+-
+-    # available only on Linux and Windows >= Vista
+-    if hasattr(_psplatform.Process, "get_process_ionice"):
+-
+-        def get_ionice(self):
+-            """Return process I/O niceness (priority).
+-
+-            On Linux this is a (ioclass, value) namedtuple.
+-            On Windows it's an integer which can be equal to 2 (normal),
+-            1 (low) or 0 (very low).
++        def num_fds(self):
++            """Return the number of file descriptors opened by this
++            process (POSIX only).
++            """
++            return self._proc.num_fds()
+ 
+-            Available on Linux and Windows > Vista only.
++    # Linux, BSD and Windows only
++    if hasattr(_psplatform.Process, "io_counters"):
++
++        def io_counters(self):
++            """Return process I/O statistics as a
++            (read_count, write_count, read_bytes, write_bytes)
++            namedtuple.
++            Those are the number of read/write calls performed and the
++            amount of bytes read and written by the process.
+             """
+-            return self._platform_impl.get_process_ionice()
++            return self._proc.io_counters()
+ 
+-        def set_ionice(self, ioclass, value=None):
+-            """Set process I/O niceness (priority).
++    # Linux and Windows >= Vista only
++    if hasattr(_psplatform.Process, "ionice_get"):
++
++        def ionice(self, ioclass=None, value=None):
++            """Get or set process I/O niceness (priority).
+ 
+             On Linux 'ioclass' is one of the IOPRIO_CLASS_* constants.
+             'value' is a number which goes from 0 to 7. The higher the
+@@ -429,58 +679,77 @@
+ 
+             Available on Linux and Windows > Vista only.
+             """
+-            return self._platform_impl.set_process_ionice(ioclass, value)
++            if ioclass is None:
++                if value is not None:
++                    raise ValueError("'ioclass' must be specified")
++                return self._proc.ionice_get()
++            else:
++                return self._proc.ionice_set(ioclass, value)
+ 
+-    # available on Windows and Linux only
+-    if hasattr(_psplatform.Process, "get_process_cpu_affinity"):
++    # Linux only
++    if hasattr(_psplatform.Process, "rlimit"):
+ 
+-        def get_cpu_affinity(self):
+-            """Get process current CPU affinity."""
+-            return self._platform_impl.get_process_cpu_affinity()
+-
+-        def set_cpu_affinity(self, cpus):
+-            """Set process current CPU affinity.
+-            'cpus' is a list of CPUs for which you want to set the
+-            affinity (e.g. [0, 1]).
++        def rlimit(self, resource, limits=None):
++            """Get or set process resource limits as a (soft, hard)
++            tuple.
++
++            'resource' is one of the RLIMIT_* constants.
++            'limits' is supposed to be a (soft, hard)  tuple.
++
++            See "man prlimit" for further info.
++            Available on Linux only.
+             """
+-            return self._platform_impl.set_process_cpu_affinity(cpus)
++            if limits is None:
++                return self._proc.rlimit(resource)
++            else:
++                return self._proc.rlimit(resource, limits)
+ 
+-    if os.name == 'nt':
++    # Windows, Linux and BSD only
++    if hasattr(_psplatform.Process, "cpu_affinity_get"):
+ 
+-        def get_num_handles(self):
+-            """Return the number of handles opened by this process
+-            (Windows only).
++        def cpu_affinity(self, cpus=None):
++            """Get or set process CPU affinity.
++            If specified 'cpus' must be a list of CPUs for which you
++            want to set the affinity (e.g. [0, 1]).
++            (Windows, Linux and BSD only).
+             """
+-            return self._platform_impl.get_num_handles()
++            # Automatically remove duplicates both on get and
++            # set (for get it's not really necessary, it's
++            # just for extra safety).
++            if cpus is None:
++                return list(set(self._proc.cpu_affinity_get()))
++            else:
++                self._proc.cpu_affinity_set(list(set(cpus)))
+ 
+-    if os.name == 'posix':
++    if _WINDOWS:
+ 
+-        def get_num_fds(self):
+-            """Return the number of file descriptors opened by this
+-            process (POSIX only).
++        def num_handles(self):
++            """Return the number of handles opened by this process
++            (Windows only).
+             """
+-            return self._platform_impl.get_num_fds()
++            return self._proc.num_handles()
+ 
+-    def get_num_ctx_switches(self):
+-        """Return the number voluntary and involuntary context switches
+-        performed by this process.
++    def num_ctx_switches(self):
++        """Return the number of voluntary and involuntary context
++        switches performed by this process.
+         """
+-        return self._platform_impl.get_num_ctx_switches()
++        return self._proc.num_ctx_switches()
+ 
+-    def get_num_threads(self):
++    def num_threads(self):
+         """Return the number of threads used by this process."""
+-        return self._platform_impl.get_process_num_threads()
++        return self._proc.num_threads()
+ 
+-    def get_threads(self):
+-        """Return threads opened by process as a list of namedtuples
+-        including thread id and thread CPU times (user/system).
++    def threads(self):
++        """Return threads opened by process as a list of
++        (id, user_time, system_time) namedtuples representing
++        thread id and thread CPU times (user/system).
+         """
+-        return self._platform_impl.get_process_threads()
++        return self._proc.threads()
+ 
+     @_assert_pid_not_reused
+-    def get_children(self, recursive=False):
++    def children(self, recursive=False):
+         """Return the children of this process as a list of Process
+-        objects pre-emptively checking whether PID has been reused.
++        instances, pre-emptively checking whether PID has been reused.
+         If recursive is True return all the parent descendants.
+ 
+         Example (A == this process):
+@@ -493,37 +762,68 @@
+             ├─ C (child)
+             └─ D (child)
+ 
+-        >>> p.get_children()
++        >>> import psutil
++        >>> p = psutil.Process()
++        >>> p.children()
+         B, C, D
+-        >>> p.get_children(recursive=True)
++        >>> p.children(recursive=True)
+         B, X, Y, C, D
+ 
+         Note that in the example above if process X disappears
+-        process Y won't be returned either as the reference to
+-        process A is lost.
++        process Y won't be listed as the reference to process A
++        is lost.
+         """
++        if hasattr(_psplatform, 'ppid_map'):
++            # Windows only: obtain a {pid:ppid, ...} dict for all running
++            # processes in one shot (faster).
++            ppid_map = _psplatform.ppid_map()
++        else:
++            ppid_map = None
++
+         ret = []
+         if not recursive:
+-            for p in process_iter():
+-                try:
+-                    if p.ppid == self.pid:
+-                        # if child happens to be older than its parent
+-                        # (self) it means child's PID has been reused
+-                        if self.create_time <= p.create_time:
+-                            ret.append(p)
+-                except NoSuchProcess:
+-                    pass
++            if ppid_map is None:
++                # 'slow' version, common to all platforms except Windows
++                for p in process_iter():
++                    try:
++                        if p.ppid() == self.pid:
++                            # if child happens to be older than its parent
++                            # (self) it means child's PID has been reused
++                            if self.create_time() <= p.create_time():
++                                ret.append(p)
++                    except (NoSuchProcess, ZombieProcess):
++                        pass
++            else:
++                # Windows only (faster)
++                for pid, ppid in ppid_map.items():
++                    if ppid == self.pid:
++                        try:
++                            child = Process(pid)
++                            # if child happens to be older than its parent
++                            # (self) it means child's PID has been reused
++                            if self.create_time() <= child.create_time():
++                                ret.append(child)
++                        except (NoSuchProcess, ZombieProcess):
++                            pass
+         else:
+             # construct a dict where 'values' are all the processes
+             # having 'key' as their parent
+-            table = defaultdict(list)
+-            for p in process_iter():
+-                try:
+-                    table[p.ppid].append(p)
+-                except NoSuchProcess:
+-                    pass
++            table = collections.defaultdict(list)
++            if ppid_map is None:
++                for p in process_iter():
++                    try:
++                        table[p.ppid()].append(p)
++                    except (NoSuchProcess, ZombieProcess):
++                        pass
++            else:
++                for pid, ppid in ppid_map.items():
++                    try:
++                        p = Process(pid)
++                        table[ppid].append(p)
++                    except (NoSuchProcess, ZombieProcess):
++                        pass
+             # At this point we have a mapping table where table[self.pid]
+-            # are the current process's children.
++            # are the current process' children.
+             # Below, we look for all descendants recursively, similarly
+             # to a recursive function call.
+             checkpids = [self.pid]
+@@ -532,8 +832,8 @@
+                     try:
+                         # if child happens to be older than its parent
+                         # (self) it means child's PID has been reused
+-                        intime = self.create_time <= child.create_time
+-                    except NoSuchProcess:
++                        intime = self.create_time() <= child.create_time()
++                    except (NoSuchProcess, ZombieProcess):
+                         pass
+                     else:
+                         if intime:
+@@ -542,42 +842,52 @@
+                                 checkpids.append(child.pid)
+         return ret
+ 
+-    def get_cpu_percent(self, interval=0.1):
++    def cpu_percent(self, interval=None):
+         """Return a float representing the current process CPU
+         utilization as a percentage.
+ 
++        When interval is 0.0 or None (default) compares process times
++        to system CPU times elapsed since last call, returning
++        immediately (non-blocking). That means that the first time
++        this is called it will return a meaningful 0.0 value.
++
+         When interval is > 0.0 compares process times to system CPU
+         times elapsed before and after the interval (blocking).
+ 
+-        When interval is 0.0 or None compares process times to system
+-        CPU times elapsed since last call, returning immediately
+-        (non-blocking).
+         In this case is recommended for accuracy that this function
+         be called with at least 0.1 seconds between calls.
+ 
+         Examples:
+ 
++          >>> import psutil
+           >>> p = psutil.Process(os.getpid())
+           >>> # blocking
+-          >>> p.get_cpu_percent(interval=1)
++          >>> p.cpu_percent(interval=1)
+           2.0
+           >>> # non-blocking (percentage since last call)
+-          >>> p.get_cpu_percent(interval=0)
++          >>> p.cpu_percent(interval=None)
+           2.9
+           >>>
+         """
+         blocking = interval is not None and interval > 0.0
++        num_cpus = cpu_count()
++        if _POSIX:
++            def timer():
++                return _timer() * num_cpus
++        else:
++            def timer():
++                return sum(cpu_times())
+         if blocking:
+-            st1 = sum(cpu_times())
+-            pt1 = self._platform_impl.get_cpu_times()
++            st1 = timer()
++            pt1 = self._proc.cpu_times()
+             time.sleep(interval)
+-            st2 = sum(cpu_times())
+-            pt2 = self._platform_impl.get_cpu_times()
++            st2 = timer()
++            pt2 = self._proc.cpu_times()
+         else:
+             st1 = self._last_sys_cpu_times
+             pt1 = self._last_proc_cpu_times
+-            st2 = sum(cpu_times())
+-            pt2 = self._platform_impl.get_cpu_times()
++            st2 = timer()
++            pt2 = self._proc.cpu_times()
+             if st1 is None or pt1 is None:
+                 self._last_sys_cpu_times = st2
+                 self._last_proc_cpu_times = pt2
+@@ -590,58 +900,58 @@
+         self._last_proc_cpu_times = pt2
+ 
+         try:
+-            # the utilization split between all CPUs
+-            overall_percent = (delta_proc / delta_time) * 100
++            # The utilization split between all CPUs.
++            # Note: a percentage > 100 is legitimate as it can result
++            # from a process with multiple threads running on different
++            # CPU cores, see:
++            # http://stackoverflow.com/questions/1032357
++            # https://github.com/giampaolo/psutil/issues/474
++            overall_percent = ((delta_proc / delta_time) * 100) * num_cpus
+         except ZeroDivisionError:
+             # interval was too low
+             return 0.0
+-        # the utilization of a single CPU
+-        single_cpu_percent = overall_percent * NUM_CPUS
+-        # on posix a percentage > 100 is legitimate
+-        # http://stackoverflow.com/questions/1032357/comprehending-top-cpu-usage
+-        # on windows we use this ugly hack to avoid troubles with float
+-        # precision issues
+-        if os.name != 'posix':
+-            if single_cpu_percent > 100.0:
+-                return 100.0
+-        return round(single_cpu_percent, 1)
+-
+-    def get_cpu_times(self):
+-        """Return a tuple whose values are process CPU user and system
+-        times. The same as os.times() but per-process.
++        else:
++            return round(overall_percent, 1)
++
++    def cpu_times(self):
++        """Return a (user, system) namedtuple representing  the
++        accumulated process time, in seconds.
++        This is the same as os.times() but per-process.
+         """
+-        return self._platform_impl.get_cpu_times()
++        return self._proc.cpu_times()
+ 
+-    def get_memory_info(self):
++    def memory_info(self):
+         """Return a tuple representing RSS (Resident Set Size) and VMS
+         (Virtual Memory Size) in bytes.
+ 
+-        On UNIX RSS and VMS are the same values shown by ps.
++        On UNIX RSS and VMS are the same values shown by 'ps'.
+ 
+-        On Windows RSS and VMS refer to "Mem Usage" and "VM Size" columns
+-        of taskmgr.exe.
++        On Windows RSS and VMS refer to "Mem Usage" and "VM Size"
++        columns of taskmgr.exe.
+         """
+-        return self._platform_impl.get_memory_info()
++        return self._proc.memory_info()
+ 
+-    def get_ext_memory_info(self):
++    def memory_info_ex(self):
+         """Return a namedtuple with variable fields depending on the
+         platform representing extended memory information about
+-        the process. All numbers are expressed in bytes.
++        this process. All numbers are expressed in bytes.
+         """
+-        return self._platform_impl.get_ext_memory_info()
++        return self._proc.memory_info_ex()
+ 
+-    def get_memory_percent(self):
++    def memory_percent(self):
+         """Compare physical system memory to process resident memory
+         (RSS) and calculate process memory utilization as a percentage.
+         """
+-        rss = self._platform_impl.get_memory_info()[0]
++        rss = self._proc.memory_info()[0]
++        # use cached value if available
++        total_phymem = _TOTAL_PHYMEM or virtual_memory().total
+         try:
+-            return (rss / float(TOTAL_PHYMEM)) * 100
++            return (rss / float(total_phymem)) * 100
+         except ZeroDivisionError:
+             return 0.0
+ 
+-    def get_memory_maps(self, grouped=True):
+-        """Return process's mapped memory regions as a list of nameduples
++    def memory_maps(self, grouped=True):
++        """Return process' mapped memory regions as a list of namedtuples
+         whose fields are variable depending on the platform.
+ 
+         If 'grouped' is True the mapped regions with the same 'path'
+@@ -651,32 +961,34 @@
+         entity and the namedtuple will also include the mapped region's
+         address space ('addr') and permission set ('perms').
+         """
+-        it = self._platform_impl.get_memory_maps()
++        it = self._proc.memory_maps()
+         if grouped:
+             d = {}
+             for tupl in it:
+                 path = tupl[2]
+                 nums = tupl[3:]
+                 try:
+-                    d[path] = map(lambda x, y: x+y, d[path], nums)
++                    d[path] = map(lambda x, y: x + y, d[path], nums)
+                 except KeyError:
+                     d[path] = nums
+-            nt = self._platform_impl.nt_mmap_grouped
+-            return [nt(path, *d[path]) for path in d]
++            nt = _psplatform.pmmap_grouped
++            return [nt(path, *d[path]) for path in d]  # NOQA
+         else:
+-            nt = self._platform_impl.nt_mmap_ext
++            nt = _psplatform.pmmap_ext
+             return [nt(*x) for x in it]
+ 
+-    def get_open_files(self):
+-        """Return files opened by process as a list of namedtuples
+-        including absolute file name and file descriptor number.
+-        """
+-        return self._platform_impl.get_open_files()
+-
+-    def get_connections(self, kind='inet'):
+-        """Return connections opened by process as a list of namedtuples.
+-        The kind parameter filters for connections that fit the following
+-        criteria:
++    def open_files(self):
++        """Return files opened by process as a list of
++        (path, fd) namedtuples including the absolute file name
++        and file descriptor number.
++        """
++        return self._proc.open_files()
++
++    def connections(self, kind='inet'):
++        """Return connections opened by process as a list of
++        (fd, family, type, laddr, raddr, status) namedtuples.
++        The 'kind' parameter filters for connections that match the
++        following criteria:
+ 
+         Kind Value      Connections using
+         inet            IPv4 and IPv6
+@@ -691,25 +1003,23 @@
+         unix            UNIX socket (both UDP and TCP protocols)
+         all             the sum of all the possible families and protocols
+         """
+-        return self._platform_impl.get_connections(kind)
++        return self._proc.connections(kind)
+ 
+-    def is_running(self):
+-        """Return whether this process is running.
+-        It also checks if PID has been reused by another process in
+-        which case returns False.
+-        """
+-        if self._gone:
+-            return False
+-        try:
+-            # Checking if pid is alive is not enough as the pid might
+-            # have been reused by another process.
+-            # pid + creation time, on the other hand, is supposed to
+-            # identify a process univocally.
+-            return self.create_time == \
+-                   self._platform_impl.get_process_create_time()
+-        except NoSuchProcess:
+-            self._gone = True
+-            return False
++    if _POSIX:
++        def _send_signal(self, sig):
++            # XXX: according to "man 2 kill" PID 0 has a special
++            # meaning as it refers to <<every process in the process
++            # group of the calling process>>, so should we prevent
++            # it here?
++            try:
++                os.kill(self.pid, sig)
++            except OSError as err:
++                if err.errno == errno.ESRCH:
++                    self._gone = True
++                    raise NoSuchProcess(self.pid, self._name)
++                if err.errno == errno.EPERM:
++                    raise AccessDenied(self.pid, self._name)
++                raise
+ 
+     @_assert_pid_not_reused
+     def send_signal(self, sig):
+@@ -718,21 +1028,11 @@
+         On Windows only SIGTERM is valid and is treated as an alias
+         for kill().
+         """
+-        if os.name == 'posix':
+-            try:
+-                os.kill(self.pid, sig)
+-            except OSError:
+-                err = sys.exc_info()[1]
+-                name = self._platform_impl._process_name
+-                if err.errno == errno.ESRCH:
+-                    self._gone = True
+-                    raise NoSuchProcess(self.pid, name)
+-                if err.errno == errno.EPERM:
+-                    raise AccessDenied(self.pid, name)
+-                raise
++        if _POSIX:
++            self._send_signal(sig)
+         else:
+             if sig == signal.SIGTERM:
+-                self._platform_impl.kill_process()
++                self._proc.kill()
+             else:
+                 raise ValueError("only SIGTERM is supported on Windows")
+ 
+@@ -740,86 +1040,82 @@
+     def suspend(self):
+         """Suspend process execution with SIGSTOP pre-emptively checking
+         whether PID has been reused.
+-        On Windows it suspends all process threads.
++        On Windows this has the effect ot suspending all process threads.
+         """
+-        if hasattr(self._platform_impl, "suspend_process"):
+-            # windows
+-            self._platform_impl.suspend_process()
++        if _POSIX:
++            self._send_signal(signal.SIGSTOP)
+         else:
+-            # posix
+-            self.send_signal(signal.SIGSTOP)
++            self._proc.suspend()
+ 
+     @_assert_pid_not_reused
+     def resume(self):
+         """Resume process execution with SIGCONT pre-emptively checking
+         whether PID has been reused.
+-        On Windows it resumes all process threads.
++        On Windows this has the effect of resuming all process threads.
+         """
+-        if hasattr(self._platform_impl, "resume_process"):
+-            # windows
+-            self._platform_impl.resume_process()
++        if _POSIX:
++            self._send_signal(signal.SIGCONT)
+         else:
+-            # posix
+-            self.send_signal(signal.SIGCONT)
++            self._proc.resume()
+ 
++    @_assert_pid_not_reused
+     def terminate(self):
+         """Terminate the process with SIGTERM pre-emptively checking
+         whether PID has been reused.
+         On Windows this is an alias for kill().
+         """
+-        self.send_signal(signal.SIGTERM)
++        if _POSIX:
++            self._send_signal(signal.SIGTERM)
++        else:
++            self._proc.kill()
+ 
+     @_assert_pid_not_reused
+     def kill(self):
+         """Kill the current process with SIGKILL pre-emptively checking
+-        whether PID has been reused."""
+-        if os.name == 'posix':
+-            self.send_signal(signal.SIGKILL)
++        whether PID has been reused.
++        """
++        if _POSIX:
++            self._send_signal(signal.SIGKILL)
+         else:
+-            self._platform_impl.kill_process()
++            self._proc.kill()
+ 
+     def wait(self, timeout=None):
+         """Wait for process to terminate and, if process is a children
+-        of the current one also return its exit code, else None.
++        of os.getpid(), also return its exit code, else None.
++
++        If the process is already terminated immediately return None
++        instead of raising NoSuchProcess.
++
++        If timeout (in seconds) is specified and process is still alive
++        raise TimeoutExpired.
++
++        To wait for multiple Process(es) use psutil.wait_procs().
+         """
+         if timeout is not None and not timeout >= 0:
+             raise ValueError("timeout must be a positive integer")
+-        return self._platform_impl.process_wait(timeout)
++        return self._proc.wait(timeout)
+ 
+-    # --- deprecated API
+ 
+-    @property
+-    def nice(self):
+-        """Get or set process niceness (priority).
+-        Deprecated, use get_nice() instead.
+-        """
+-        msg = "this property is deprecated; use Process.get_nice() method instead"
+-        warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
+-        return self.get_nice()
+-
+-    @nice.setter
+-    def nice(self, value):
+-        # invoked on "p.nice = num"; change process niceness
+-        # deprecated in favor of set_nice()
+-        msg = "this property is deprecated; use Process.set_nice() method instead"
+-        warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
+-        return self.set_nice(value)
++# =====================================================================
++# --- Popen class
++# =====================================================================
+ 
+ 
+ class Popen(Process):
+     """A more convenient interface to stdlib subprocess module.
+     It starts a sub process and deals with it exactly as when using
+     subprocess.Popen class but in addition also provides all the
+-    property and methods of psutil.Process class in a single interface:
++    properties and methods of psutil.Process class as a unified
++    interface:
+ 
+       >>> import psutil
+       >>> from subprocess import PIPE
+-      >>> p = psutil.Popen(["/usr/bin/python", "-c", "print 'hi'"], stdout=PIPE)
+-      >>> p.name
++      >>> p = psutil.Popen(["python", "-c", "print 'hi'"], stdout=PIPE)
++      >>> p.name()
+       'python'
+-      >>> p.uids
++      >>> p.uids()
+       user(real=1000, effective=1000, saved=1000)
+-      >>> p.username
++      >>> p.username()
+       'giampaolo'
+       >>> p.communicate()
+       ('hi\n', None)
+@@ -831,28 +1127,24 @@
+     For method names common to both classes such as kill(), terminate()
+     and wait(), psutil.Process implementation takes precedence.
+ 
+-    For a complete documentation refers to:
++    Unlike subprocess.Popen this class pre-emptively checks wheter PID
++    has been reused on send_signal(), terminate() and kill() so that
++    you don't accidentally terminate another process, fixing
++    http://bugs.python.org/issue6973.
++
++    For a complete documentation refer to:
+     http://docs.python.org/library/subprocess.html
+     """
+ 
+     def __init__(self, *args, **kwargs):
++        # Explicitly avoid to raise NoSuchProcess in case the process
++        # spawned by subprocess.Popen terminates too quickly, see:
++        # https://github.com/giampaolo/psutil/issues/193
+         self.__subproc = subprocess.Popen(*args, **kwargs)
+-        self._pid = self.__subproc.pid
+-        self._gone = False
+-        self._ppid = None
+-        self._platform_impl = _psplatform.Process(self._pid)
+-        self._last_sys_cpu_times = None
+-        self._last_proc_cpu_times = None
+-        try:
+-            self.create_time
+-        except AccessDenied:
+-            pass
+-        except NoSuchProcess:
+-            raise NoSuchProcess(self._pid, None,
+-                                "no process found with pid %s" % self._pid)
++        self._init(self.__subproc.pid, _ignore_nsp=True)
+ 
+     def __dir__(self):
+-        return list(set(dir(Popen) + dir(subprocess.Popen)))
++        return sorted(set(dir(Popen) + dir(subprocess.Popen)))
+ 
+     def __getattribute__(self, name):
+         try:
+@@ -862,21 +1154,50 @@
+                 return object.__getattribute__(self.__subproc, name)
+             except AttributeError:
+                 raise AttributeError("%s instance has no attribute '%s'"
+-                                      %(self.__class__.__name__, name))
++                                     % (self.__class__.__name__, name))
++
++    def wait(self, timeout=None):
++        if self.__subproc.returncode is not None:
++            return self.__subproc.returncode
++        ret = super(Popen, self).wait(timeout)
++        self.__subproc.returncode = ret
++        return ret
+ 
+ 
+ # =====================================================================
+ # --- system processes related functions
+ # =====================================================================
+ 
+-get_pid_list = _psplatform.get_pid_list
+-pid_exists = _psplatform.pid_exists
++
++def pids():
++    """Return a list of current running PIDs."""
++    return _psplatform.pids()
++
++
++def pid_exists(pid):
++    """Return True if given PID exists in the current process list.
++    This is faster than doing "pid in psutil.pids()" and
++    should be preferred.
++    """
++    if pid < 0:
++        return False
++    elif pid == 0 and _POSIX:
++        # On POSIX we use os.kill() to determine PID existence.
++        # According to "man 2 kill" PID 0 has a special meaning
++        # though: it refers to <<every process in the process
++        # group of the calling process>> and that is not we want
++        # to do here.
++        return pid in pids()
++    else:
++        return _psplatform.pid_exists(pid)
++
+ 
+ _pmap = {}
+ 
++
+ def process_iter():
+-    """Return a generator yielding a Process class instance for all
+-    running processes on the local machine.
++    """Return a generator yielding a Process instance for all
++    running processes.
+ 
+     Every new Process instance is only created once and then cached
+     into an internal table which is updated every time this is used.
+@@ -896,14 +1217,14 @@
+     def remove(pid):
+         _pmap.pop(pid, None)
+ 
+-    a = set(get_pid_list())
++    a = set(pids())
+     b = set(_pmap.keys())
+     new_pids = a - b
+     gone_pids = b - a
+ 
+     for pid in gone_pids:
+         remove(pid)
+-    for pid, proc in sorted(list(_pmap.items()) + \
++    for pid, proc in sorted(list(_pmap.items()) +
+                             list(dict.fromkeys(new_pids).items())):
+         try:
+             if proc is None:  # new process
+@@ -923,15 +1244,123 @@
+             # has been reused. Just return the cached version.
+             yield proc
+ 
++
++def wait_procs(procs, timeout=None, callback=None):
++    """Convenience function which waits for a list of processes to
++    terminate.
++
++    Return a (gone, alive) tuple indicating which processes
++    are gone and which ones are still alive.
++
++    The gone ones will have a new 'returncode' attribute indicating
++    process exit status (may be None).
++
++    'callback' is a function which gets called every time a process
++    terminates (a Process instance is passed as callback argument).
++
++    Function will return as soon as all processes terminate or when
++    timeout occurs.
++
++    Typical use case is:
++
++     - send SIGTERM to a list of processes
++     - give them some time to terminate
++     - send SIGKILL to those ones which are still alive
++
++    Example:
++
++    >>> def on_terminate(proc):
++    ...     print("process {} terminated".format(proc))
++    ...
++    >>> for p in procs:
++    ...    p.terminate()
++    ...
++    >>> gone, alive = wait_procs(procs, timeout=3, callback=on_terminate)
++    >>> for p in alive:
++    ...     p.kill()
++    """
++    def check_gone(proc, timeout):
++        try:
++            returncode = proc.wait(timeout=timeout)
++        except TimeoutExpired:
++            pass
++        else:
++            if returncode is not None or not proc.is_running():
++                proc.returncode = returncode
++                gone.add(proc)
++                if callback is not None:
++                    callback(proc)
++
++    if timeout is not None and not timeout >= 0:
++        msg = "timeout must be a positive integer, got %s" % timeout
++        raise ValueError(msg)
++    gone = set()
++    alive = set(procs)
++    if callback is not None and not callable(callback):
++        raise TypeError("callback %r is not a callable" % callable)
++    if timeout is not None:
++        deadline = _timer() + timeout
++
++    while alive:
++        if timeout is not None and timeout <= 0:
++            break
++        for proc in alive:
++            # Make sure that every complete iteration (all processes)
++            # will last max 1 sec.
++            # We do this because we don't want to wait too long on a
++            # single process: in case it terminates too late other
++            # processes may disappear in the meantime and their PID
++            # reused.
++            max_timeout = 1.0 / len(alive)
++            if timeout is not None:
++                timeout = min((deadline - _timer()), max_timeout)
++                if timeout <= 0:
++                    break
++                check_gone(proc, timeout)
++            else:
++                check_gone(proc, max_timeout)
++        alive = alive - gone
++
++    if alive:
++        # Last attempt over processes survived so far.
++        # timeout == 0 won't make this function wait any further.
++        for proc in alive:
++            check_gone(proc, 0)
++        alive = alive - gone
++
++    return (list(gone), list(alive))
++
++
+ # =====================================================================
+ # --- CPU related functions
+ # =====================================================================
+ 
++
++@memoize
++def cpu_count(logical=True):
++    """Return the number of logical CPUs in the system (same as
++    os.cpu_count() in Python 3.4).
++
++    If logical is False return the number of physical cores only
++    (e.g. hyper thread CPUs are excluded).
++
++    Return None if undetermined.
++
++    The return value is cached after first call.
++    If desired cache can be cleared like this:
++
++    >>> psutil.cpu_count.cache_clear()
++    """
++    if logical:
++        return _psplatform.cpu_count_logical()
++    else:
++        return _psplatform.cpu_count_physical()
++
++
+ def cpu_times(percpu=False):
+-    """Return system-wide CPU times as a namedtuple object.
+-    Every CPU time represents the time CPU has spent in the given mode.
+-    The attributes availability varies depending on the platform.
+-    Here follows a list of all available attributes:
++    """Return system-wide CPU times as a namedtuple.
++    Every CPU time represents the seconds the CPU has spent in the given mode.
++    The namedtuple's fields availability varies depending on the platform:
+      - user
+      - system
+      - idle
+@@ -943,21 +1372,22 @@
+      - guest (Linux >= 2.6.24)
+      - guest_nice (Linux >= 3.2.0)
+ 
+-    When percpu is True return a list of nameduples for each CPU.
++    When percpu is True return a list of namedtuples for each CPU.
+     First element of the list refers to first CPU, second element
+     to second CPU and so on.
+     The order of the list is consistent across calls.
+     """
+     if not percpu:
+-        return _psplatform.get_system_cpu_times()
++        return _psplatform.cpu_times()
+     else:
+-        return _psplatform.get_system_per_cpu_times()
++        return _psplatform.per_cpu_times()
+ 
+ 
+ _last_cpu_times = cpu_times()
+ _last_per_cpu_times = cpu_times(percpu=True)
+ 
+-def cpu_percent(interval=0.1, percpu=False):
++
++def cpu_percent(interval=None, percpu=False):
+     """Return a float representing the current system-wide CPU
+     utilization as a percentage.
+ 
+@@ -965,7 +1395,9 @@
+     and after the interval (blocking).
+ 
+     When interval is 0.0 or None compares system CPU times elapsed
+-    since last call or module import, returning immediately.
++    since last call or module import, returning immediately (non
++    blocking). That means the first time this is called it will
++    return a meaningless 0.0 value which you should ignore.
+     In this case is recommended for accuracy that this function be
+     called with at least 0.1 seconds between calls.
+ 
+@@ -986,7 +1418,7 @@
+       [2.0, 1.0]
+       >>>
+       >>> # non-blocking (percentage since last call)
+-      >>> psutil.cpu_percent(interval=0)
++      >>> psutil.cpu_percent(interval=None)
+       2.9
+       >>>
+     """
+@@ -1038,9 +1470,9 @@
+ # the same program.
+ _last_cpu_times_2 = _last_cpu_times
+ _last_per_cpu_times_2 = _last_per_cpu_times
+-_ptime_cpu_perc_nt = None
+ 
+-def cpu_times_percent(interval=0.1, percpu=False):
++
++def cpu_times_percent(interval=None, percpu=False):
+     """Same as cpu_percent() but provides utilization percentages
+     for each specific CPU time as is returned by cpu_times().
+     For instance, on Linux we'll get:
+@@ -1058,7 +1490,6 @@
+     blocking = interval is not None and interval > 0.0
+ 
+     def calculate(t1, t2):
+-        global _ptime_cpu_perc_nt
+         nums = []
+         all_delta = sum(t2) - sum(t1)
+         for field in t1._fields:
+@@ -1067,10 +1498,26 @@
+                 field_perc = (100 * field_delta) / all_delta
+             except ZeroDivisionError:
+                 field_perc = 0.0
+-            nums.append(round(field_perc, 1))
+-        if _ptime_cpu_perc_nt is None:
+-            _ptime_cpu_perc_nt = namedtuple('cpupercent', ' '.join(t1._fields))
+-        return _ptime_cpu_perc_nt(*nums)
++            field_perc = round(field_perc, 1)
++            if _WINDOWS:
++                # XXX
++                # Work around:
++                # https://github.com/giampaolo/psutil/issues/392
++                # CPU times are always supposed to increase over time
++                # or at least remain the same and that's because time
++                # cannot go backwards.
++                # Surprisingly sometimes this might not be the case on
++                # Windows where 'system' CPU time can be smaller
++                # compared to the previous call, resulting in corrupted
++                # percentages (< 0 or > 100).
++                # I really don't know what to do about that except
++                # forcing the value to 0 or 100.
++                if field_perc > 100.0:
++                    field_perc = 100.0
++                elif field_perc < 0.0:
++                    field_perc = 0.0
++            nums.append(field_perc)
++        return _psplatform.scputimes(*nums)
+ 
+     # system-wide usage
+     if not percpu:
+@@ -1094,10 +1541,12 @@
+             ret.append(calculate(t1, t2))
+         return ret
+ 
++
+ # =====================================================================
+ # --- system memory related functions
+ # =====================================================================
+ 
++
+ def virtual_memory():
+     """Return statistics about system memory usage as a namedtuple
+     including the following fields, expressed in bytes:
+@@ -1151,11 +1600,16 @@
+     The sum of 'used' and 'available' does not necessarily equal total.
+     On Windows 'available' and 'free' are the same.
+     """
+-    return _psplatform.virtual_memory()
++    global _TOTAL_PHYMEM
++    ret = _psplatform.virtual_memory()
++    # cached for later use in Process.memory_percent()
++    _TOTAL_PHYMEM = ret.total
++    return ret
++
+ 
+ def swap_memory():
+     """Return system swap memory statistics as a namedtuple including
+-    the following attributes:
++    the following fields:
+ 
+      - total:   total swap memory in bytes
+      - used:    used swap memory in bytes
+@@ -1168,30 +1622,35 @@
+     """
+     return _psplatform.swap_memory()
+ 
++
+ # =====================================================================
+ # --- disks/paritions related functions
+ # =====================================================================
+ 
++
+ def disk_usage(path):
+     """Return disk usage statistics about the given path as a namedtuple
+     including total, used and free space expressed in bytes plus the
+     percentage usage.
+     """
+-    return _psplatform.get_disk_usage(path)
++    return _psplatform.disk_usage(path)
++
+ 
+ def disk_partitions(all=False):
+-    """Return mounted partitions as a list of namedtuples including
+-    device, mount point, filesystem type and mount options (a raw
+-    string separated by commas which may vary depending on the platform).
++    """Return mounted partitions as a list of
++    (device, mountpoint, fstype, opts) namedtuple.
++    'opts' field is a raw string separated by commas indicating mount
++    options which may vary depending on the platform.
+ 
+     If "all" parameter is False return physical devices only and ignore
+     all others.
+     """
+     return _psplatform.disk_partitions(all)
+ 
++
+ def disk_io_counters(perdisk=False):
+     """Return system disk I/O statistics as a namedtuple including
+-    the following attributes:
++    the following fields:
+ 
+      - read_count:  number of reads
+      - write_count: number of writes
+@@ -1202,7 +1661,7 @@
+ 
+     If perdisk is True return the same information for every
+     physical disk installed on the system as a dictionary
+-    with partition names as the keys and the namedutuple
++    with partition names as the keys and the namedtuple
+     described above as the values.
+ 
+     On recent Windows versions 'diskperf -y' command may need to be
+@@ -1213,18 +1672,20 @@
+         raise RuntimeError("couldn't find any physical disk")
+     if perdisk:
+         for disk, fields in rawdict.items():
+-            rawdict[disk] = _nt_disk_iostat(*fields)
++            rawdict[disk] = _common.sdiskio(*fields)
+         return rawdict
+     else:
+-        return _nt_disk_iostat(*[sum(x) for x in zip(*rawdict.values())])
++        return _common.sdiskio(*[sum(x) for x in zip(*rawdict.values())])
++
+ 
+ # =====================================================================
+ # --- network related functions
+ # =====================================================================
+ 
+-def network_io_counters(pernic=False):
++
++def net_io_counters(pernic=False):
+     """Return network I/O statistics as a namedtuple including
+-    the following attributes:
++    the following fields:
+ 
+      - bytes_sent:   number of bytes sent
+      - bytes_recv:   number of bytes received
+@@ -1241,29 +1702,114 @@
+     with network interface names as the keys and the namedtuple
+     described above as the values.
+     """
+-    rawdict = _psplatform.network_io_counters()
++    rawdict = _psplatform.net_io_counters()
+     if not rawdict:
+         raise RuntimeError("couldn't find any network interface")
+     if pernic:
+         for nic, fields in rawdict.items():
+-            rawdict[nic] = _nt_net_iostat(*fields)
++            rawdict[nic] = _common.snetio(*fields)
+         return rawdict
+     else:
+-        return _nt_net_iostat(*[sum(x) for x in zip(*rawdict.values())])
++        return _common.snetio(*[sum(x) for x in zip(*rawdict.values())])
++
++
++def net_connections(kind='inet'):
++    """Return system-wide connections as a list of
++    (fd, family, type, laddr, raddr, status, pid) namedtuples.
++    In case of limited privileges 'fd' and 'pid' may be set to -1
++    and None respectively.
++    The 'kind' parameter filters for connections that fit the
++    following criteria:
++
++    Kind Value      Connections using
++    inet            IPv4 and IPv6
++    inet4           IPv4
++    inet6           IPv6
++    tcp             TCP
++    tcp4            TCP over IPv4
++    tcp6            TCP over IPv6
++    udp             UDP
++    udp4            UDP over IPv4
++    udp6            UDP over IPv6
++    unix            UNIX socket (both UDP and TCP protocols)
++    all             the sum of all the possible families and protocols
++
++    On OSX this function requires root privileges.
++    """
++    return _psplatform.net_connections(kind)
++
++
++def net_if_addrs():
++    """Return the addresses associated to each NIC (network interface
++    card) installed on the system as a dictionary whose keys are the
++    NIC names and value is a list of namedtuples for each address
++    assigned to the NIC. Each namedtuple includes 4 fields:
++
++     - family
++     - address
++     - netmask
++     - broadcast
++
++    'family' can be either socket.AF_INET, socket.AF_INET6 or
++    psutil.AF_LINK, which refers to a MAC address.
++    'address' is the primary address, 'netmask' and 'broadcast'
++    may be None.
++    Note: you can have more than one address of the same family
++    associated with each interface.
++    """
++    has_enums = sys.version_info >= (3, 4)
++    if has_enums:
++        import socket
++    rawlist = _psplatform.net_if_addrs()
++    rawlist.sort(key=lambda x: x[1])  # sort by family
++    ret = collections.defaultdict(list)
++    for name, fam, addr, mask, broadcast in rawlist:
++        if has_enums:
++            try:
++                fam = socket.AddressFamily(fam)
++            except ValueError:
++                if os.name == 'nt' and fam == -1:
++                    fam = _psplatform.AF_LINK
++                elif (hasattr(_psplatform, "AF_LINK") and
++                        _psplatform.AF_LINK == fam):
++                    # Linux defines AF_LINK as an alias for AF_PACKET.
++                    # We re-set the family here so that repr(family)
++                    # will show AF_LINK rather than AF_PACKET
++                    fam = _psplatform.AF_LINK
++        ret[name].append(_common.snic(fam, addr, mask, broadcast))
++    return dict(ret)
++
++
++def net_if_stats():
++    """Return information about each NIC (network interface card)
++    installed on the system as a dictionary whose keys are the
++    NIC names and value is a namedtuple with the following fields:
++
++     - isup: whether the interface is up (bool)
++     - duplex: can be either NIC_DUPLEX_FULL, NIC_DUPLEX_HALF or
++               NIC_DUPLEX_UNKNOWN
++     - speed: the NIC speed expressed in mega bits (MB); if it can't
++              be determined (e.g. 'localhost') it will be set to 0.
++     - mtu: the maximum transmission unit expressed in bytes.
++    """
++    return _psplatform.net_if_stats()
++
+ 
+ # =====================================================================
+ # --- other system related functions
+ # =====================================================================
+ 
+-def get_boot_time():
+-    """Return the system boot time expressed in seconds since the epoch.
+-    This is also available as psutil.BOOT_TIME.
+-    """
+-    return _psplatform.get_system_boot_time()
+ 
+-def get_users():
++def boot_time():
++    """Return the system boot time expressed in seconds since the epoch."""
++    # Note: we are not caching this because it is subject to
++    # system clock updates.
++    return _psplatform.boot_time()
++
++
++def users():
+     """Return users currently connected on the system as a list of
+-    namedtuples including the following attributes.
++    namedtuples including the following fields.
+ 
+      - user: the name of the user
+      - terminal: the tty or pseudo-tty associated with the user, if any.
+@@ -1271,68 +1817,25 @@
+      - started: the creation time as a floating point number expressed in
+        seconds since the epoch.
+     """
+-    return _psplatform.get_system_users()
+-
+-# =====================================================================
+-# --- deprecated functions
+-# =====================================================================
++    return _psplatform.users()
+ 
+-@_deprecated()
+-def get_process_list():
+-    """Return a list of Process class instances for all running
+-    processes on the local machine (deprecated).
+-    """
+-    return list(process_iter())
+-
+-@_deprecated()
+-def phymem_usage():
+-    """Return the amount of total, used and free physical memory
+-    on the system in bytes plus the percentage usage.
+-    Deprecated by psutil.virtual_memory().
+-    """
+-    mem = virtual_memory()
+-    return _nt_sysmeminfo(mem.total, mem.used, mem.free, mem.percent)
+-
+-@_deprecated("psutil.swap_memory()")
+-def virtmem_usage():
+-    return swap_memory()
+-
+-@_deprecated("psutil.phymem_usage().free")
+-def avail_phymem():
+-    return phymem_usage().free
+-
+-@_deprecated("psutil.phymem_usage().used")
+-def used_phymem():
+-    return phymem_usage().used
+-
+-@_deprecated("psutil.virtmem_usage().total")
+-def total_virtmem():
+-    return virtmem_usage().total
+-
+-@_deprecated("psutil.virtmem_usage().used")
+-def used_virtmem():
+-    return virtmem_usage().used
+-
+-@_deprecated("psutil.virtmem_usage().free")
+-def avail_virtmem():
+-    return virtmem_usage().free
+ 
+ def test():
+     """List info of all currently running processes emulating ps aux
+     output.
+     """
+     import datetime
+-    from psutil._compat import print_
+ 
+     today_day = datetime.date.today()
+     templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s  %s"
+-    attrs = ['pid', 'username', 'get_cpu_percent', 'get_memory_percent', 'name',
+-             'get_cpu_times', 'create_time', 'get_memory_info']
+-    if os.name == 'posix':
++    attrs = ['pid', 'cpu_percent', 'memory_percent', 'name', 'cpu_times',
++             'create_time', 'memory_info']
++    if _POSIX:
++        attrs.append('uids')
+         attrs.append('terminal')
+-    print_(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY", "START",
+-                    "TIME", "COMMAND"))
+-    for p in sorted(process_iter(), key=lambda p: p.pid):
++    print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY",
++                   "START", "TIME", "COMMAND"))
++    for p in process_iter():
+         try:
+             pinfo = p.as_dict(attrs, ad_value='')
+         except NoSuchProcess:
+@@ -1346,30 +1849,44 @@
+                     ctime = ctime.strftime("%b%d")
+             else:
+                 ctime = ''
+-            cputime = time.strftime("%M:%S", time.localtime(sum(pinfo['cpu_times'])))
+-            user = pinfo['username']
+-            if os.name == 'nt' and '\\' in user:
++            cputime = time.strftime("%M:%S",
++                                    time.localtime(sum(pinfo['cpu_times'])))
++            try:
++                user = p.username()
++            except KeyError:
++                if _POSIX:
++                    if pinfo['uids']:
++                        user = str(pinfo['uids'].real)
++                    else:
++                        user = ''
++                else:
++                    raise
++            except Error:
++                user = ''
++            if _WINDOWS and '\\' in user:
+                 user = user.split('\\')[1]
+             vms = pinfo['memory_info'] and \
+-                  int(pinfo['memory_info'].vms / 1024) or '?'
++                int(pinfo['memory_info'].vms / 1024) or '?'
+             rss = pinfo['memory_info'] and \
+-                  int(pinfo['memory_info'].rss / 1024) or '?'
++                int(pinfo['memory_info'].rss / 1024) or '?'
+             memp = pinfo['memory_percent'] and \
+-                   round(pinfo['memory_percent'], 1) or '?'
+-            print_(templ % (user[:10],
+-                            pinfo['pid'],
+-                            pinfo['cpu_percent'],
+-                            memp,
+-                            vms,
+-                            rss,
+-                            pinfo.get('terminal', '') or '?',
+-                            ctime,
+-                            cputime,
+-                            pinfo['name'].strip() or '?'))
++                round(pinfo['memory_percent'], 1) or '?'
++            print(templ % (
++                user[:10],
++                pinfo['pid'],
++                pinfo['cpu_percent'],
++                memp,
++                vms,
++                rss,
++                pinfo.get('terminal', '') or '?',
++                ctime,
++                cputime,
++                pinfo['name'].strip() or '?'))
+ 
+-if __name__ == "__main__":
+-    test()
+ 
+-del property, cached_property, division
++del memoize, division
+ if sys.version_info < (3, 0):
+     del num
++
++if __name__ == "__main__":
++    test()
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_common.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_common.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,19 +1,74 @@
+-#/usr/bin/env python
++# /usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """Common objects shared by all _ps* modules."""
+ 
+ from __future__ import division
+-import sys
++import errno
++import functools
+ import os
++import socket
+ import stat
+-import errno
+-import warnings
++import sys
++from collections import namedtuple
++from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
++try:
++    import threading
++except ImportError:
++    import dummy_threading as threading
++
++if sys.version_info >= (3, 4):
++    import enum
++else:
++    enum = None
++
++
++# --- constants
++
++AF_INET6 = getattr(socket, 'AF_INET6', None)
++AF_UNIX = getattr(socket, 'AF_UNIX', None)
++
++STATUS_RUNNING = "running"
++STATUS_SLEEPING = "sleeping"
++STATUS_DISK_SLEEP = "disk-sleep"
++STATUS_STOPPED = "stopped"
++STATUS_TRACING_STOP = "tracing-stop"
++STATUS_ZOMBIE = "zombie"
++STATUS_DEAD = "dead"
++STATUS_WAKE_KILL = "wake-kill"
++STATUS_WAKING = "waking"
++STATUS_IDLE = "idle"  # BSD
++STATUS_LOCKED = "locked"  # BSD
++STATUS_WAITING = "waiting"  # BSD
++
++CONN_ESTABLISHED = "ESTABLISHED"
++CONN_SYN_SENT = "SYN_SENT"
++CONN_SYN_RECV = "SYN_RECV"
++CONN_FIN_WAIT1 = "FIN_WAIT1"
++CONN_FIN_WAIT2 = "FIN_WAIT2"
++CONN_TIME_WAIT = "TIME_WAIT"
++CONN_CLOSE = "CLOSE"
++CONN_CLOSE_WAIT = "CLOSE_WAIT"
++CONN_LAST_ACK = "LAST_ACK"
++CONN_LISTEN = "LISTEN"
++CONN_CLOSING = "CLOSING"
++CONN_NONE = "NONE"
++
++if enum is None:
++    NIC_DUPLEX_FULL = 2
++    NIC_DUPLEX_HALF = 1
++    NIC_DUPLEX_UNKNOWN = 0
++else:
++    class NicDuplex(enum.IntEnum):
++        NIC_DUPLEX_FULL = 2
++        NIC_DUPLEX_HALF = 1
++        NIC_DUPLEX_UNKNOWN = 0
++
++    globals().update(NicDuplex.__members__)
+ 
+-from psutil._compat import namedtuple, long, wraps
+ 
+ # --- functions
+ 
+@@ -28,77 +83,46 @@
+     else:
+         return ret
+ 
+-class constant(int):
+-    """A constant type; overrides base int to provide a useful name on str()."""
+ 
+-    def __new__(cls, value, name, doc=None):
+-        inst = super(constant, cls).__new__(cls, value)
+-        inst._name = name
+-        if doc is not None:
+-            inst.__doc__ = doc
+-        return inst
+-
+-    def __str__(self):
+-        return self._name
+-
+-    def __eq__(self, other):
+-        # Use both int or str values when comparing for equality
+-        # (useful for serialization):
+-        # >>> st = constant(0, "running")
+-        # >>> st == 0
+-        # True
+-        # >>> st == 'running'
+-        # True
+-        if isinstance(other, int):
+-            return int(self) == other
+-        if isinstance(other, long):
+-            return long(self) == other
+-        if isinstance(other, str):
+-            return self._name == other
+-        return False
+-
+-    def __ne__(self, other):
+-        return not self.__eq__(other)
+-
+-def memoize(f):
+-    """A simple memoize decorator for functions."""
+-    cache= {}
+-    def memf(*x):
+-        if x not in cache:
+-            cache[x] = f(*x)
+-        return cache[x]
+-    return memf
+-
+-class cached_property(object):
+-    """A memoize decorator for class properties."""
+-    enabled = True
+-
+-    def __init__(self, func):
+-        self.func = func
+-
+-    def __get__(self, instance, type):
+-        ret = self.func(instance)
+-        if self.enabled:
+-            instance.__dict__[self.func.__name__] = ret
++def memoize(fun):
++    """A simple memoize decorator for functions supporting (hashable)
++    positional arguments.
++    It also provides a cache_clear() function for clearing the cache:
++
++    >>> @memoize
++    ... def foo()
++    ...     return 1
++    ...
++    >>> foo()
++    1
++    >>> foo.cache_clear()
++    >>>
++    """
++    @functools.wraps(fun)
++    def wrapper(*args, **kwargs):
++        key = (args, frozenset(sorted(kwargs.items())))
++        lock.acquire()
++        try:
++            try:
++                return cache[key]
++            except KeyError:
++                ret = cache[key] = fun(*args, **kwargs)
++        finally:
++            lock.release()
+         return ret
+ 
+-# http://goo.gl/jYLvf
+-def deprecated(replacement=None):
+-    """A decorator which can be used to mark functions as deprecated."""
+-    def outer(fun):
+-        msg = "psutil.%s is deprecated" % fun.__name__
+-        if replacement is not None:
+-            msg += "; use %s instead" % replacement
+-        if fun.__doc__ is None:
+-            fun.__doc__ = msg
+-
+-        @wraps(fun)
+-        def inner(*args, **kwargs):
+-            warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
+-            return fun(*args, **kwargs)
+-
+-        return inner
+-    return outer
++    def cache_clear():
++        """Clear cache."""
++        lock.acquire()
++        try:
++            cache.clear()
++        finally:
++            lock.release()
++
++    lock = threading.RLock()
++    cache = {}
++    wrapper.cache_clear = cache_clear
++    return wrapper
+ 
+ 
+ def isfile_strict(path):
+@@ -108,8 +132,7 @@
+     """
+     try:
+         st = os.stat(path)
+-    except OSError:
+-        err = sys.exc_info()[1]
++    except OSError as err:
+         if err.errno in (errno.EPERM, errno.EACCES):
+             raise
+         return False
+@@ -117,74 +140,107 @@
+         return stat.S_ISREG(st.st_mode)
+ 
+ 
+-# --- constants
++def sockfam_to_enum(num):
++    """Convert a numeric socket family value to an IntEnum member.
++    If it's not a known member, return the numeric value itself.
++    """
++    if enum is None:
++        return num
++    try:
++        return socket.AddressFamily(num)
++    except (ValueError, AttributeError):
++        return num
+ 
+-STATUS_RUNNING = constant(0, "running")
+-STATUS_SLEEPING = constant(1, "sleeping")
+-STATUS_DISK_SLEEP = constant(2, "disk sleep")
+-STATUS_STOPPED = constant(3, "stopped")
+-STATUS_TRACING_STOP = constant(4, "tracing stop")
+-STATUS_ZOMBIE = constant(5, "zombie")
+-STATUS_DEAD = constant(6, "dead")
+-STATUS_WAKE_KILL = constant(7, "wake kill")
+-STATUS_WAKING = constant(8, "waking")
+-STATUS_IDLE = constant(9, "idle")  # BSD
+-STATUS_LOCKED = constant(10, "locked")  # BSD
+-STATUS_WAITING = constant(11, "waiting")  # BSD
+ 
+-# --- Process.get_connections() 'kind' parameter mapping
++def socktype_to_enum(num):
++    """Convert a numeric socket type value to an IntEnum member.
++    If it's not a known member, return the numeric value itself.
++    """
++    if enum is None:
++        return num
++    try:
++        return socket.AddressType(num)
++    except (ValueError, AttributeError):
++        return num
+ 
+-import socket
+-from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
+-AF_INET6 = getattr(socket, 'AF_INET6', None)
+-AF_UNIX = getattr(socket, 'AF_UNIX', None)
++
++# --- Process.connections() 'kind' parameter mapping
+ 
+ conn_tmap = {
+-    "all"  : ([AF_INET, AF_INET6, AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
+-    "tcp"  : ([AF_INET, AF_INET6], [SOCK_STREAM]),
+-    "tcp4" : ([AF_INET],           [SOCK_STREAM]),
+-    "udp"  : ([AF_INET, AF_INET6], [SOCK_DGRAM]),
+-    "udp4" : ([AF_INET],           [SOCK_DGRAM]),
+-    "inet" : ([AF_INET, AF_INET6], [SOCK_STREAM, SOCK_DGRAM]),
+-    "inet4": ([AF_INET],           [SOCK_STREAM, SOCK_DGRAM]),
+-    "inet6": ([AF_INET6],          [SOCK_STREAM, SOCK_DGRAM]),
++    "all": ([AF_INET, AF_INET6, AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
++    "tcp": ([AF_INET, AF_INET6], [SOCK_STREAM]),
++    "tcp4": ([AF_INET], [SOCK_STREAM]),
++    "udp": ([AF_INET, AF_INET6], [SOCK_DGRAM]),
++    "udp4": ([AF_INET], [SOCK_DGRAM]),
++    "inet": ([AF_INET, AF_INET6], [SOCK_STREAM, SOCK_DGRAM]),
++    "inet4": ([AF_INET], [SOCK_STREAM, SOCK_DGRAM]),
++    "inet6": ([AF_INET6], [SOCK_STREAM, SOCK_DGRAM]),
+ }
+ 
+ if AF_INET6 is not None:
+     conn_tmap.update({
+-        "tcp6" : ([AF_INET6],          [SOCK_STREAM]),
+-        "udp6" : ([AF_INET6],          [SOCK_DGRAM]),
++        "tcp6": ([AF_INET6], [SOCK_STREAM]),
++        "udp6": ([AF_INET6], [SOCK_DGRAM]),
+     })
+ 
+ if AF_UNIX is not None:
+     conn_tmap.update({
+-        "unix" : ([AF_UNIX],           [SOCK_STREAM, SOCK_DGRAM]),
++        "unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
+     })
+ 
++del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM
+ 
+-del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM, socket
+ 
+-# --- namedtuples
++# --- namedtuples for psutil.* system-related functions
+ 
+-# system
+-nt_sysmeminfo = namedtuple('usage', 'total used free percent')
+-# XXX - would 'available' be better than 'free' as for virtual_memory() nt?
+-nt_swapmeminfo = namedtuple('swap', 'total used free percent sin sout')
+-nt_diskinfo = namedtuple('usage', 'total used free percent')
+-nt_partition = namedtuple('partition',  'device mountpoint fstype opts')
+-nt_net_iostat = namedtuple('iostat',
+-    'bytes_sent bytes_recv packets_sent packets_recv errin errout dropin dropout')
+-nt_disk_iostat = namedtuple('iostat', 'read_count write_count read_bytes write_bytes read_time write_time')
+-nt_user = namedtuple('user', 'name terminal host started')
+-
+-# processes
+-nt_meminfo = namedtuple('meminfo', 'rss vms')
+-nt_cputimes = namedtuple('cputimes', 'user system')
+-nt_openfile = namedtuple('openfile', 'path fd')
+-nt_connection = namedtuple('connection', 'fd family type local_address remote_address status')
+-nt_thread = namedtuple('thread', 'id user_time system_time')
+-nt_uids = namedtuple('user', 'real effective saved')
+-nt_gids = namedtuple('group', 'real effective saved')
+-nt_io = namedtuple('io', 'read_count write_count read_bytes write_bytes')
+-nt_ionice = namedtuple('ionice', 'ioclass value')
+-nt_ctxsw = namedtuple('amount', 'voluntary involuntary')
++# psutil.swap_memory()
++sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
++                             'sout'])
++# psutil.disk_usage()
++sdiskusage = namedtuple('sdiskusage', ['total', 'used', 'free', 'percent'])
++# psutil.disk_io_counters()
++sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
++                                 'read_bytes', 'write_bytes',
++                                 'read_time', 'write_time'])
++# psutil.disk_partitions()
++sdiskpart = namedtuple('sdiskpart', ['device', 'mountpoint', 'fstype', 'opts'])
++# psutil.net_io_counters()
++snetio = namedtuple('snetio', ['bytes_sent', 'bytes_recv',
++                               'packets_sent', 'packets_recv',
++                               'errin', 'errout',
++                               'dropin', 'dropout'])
++# psutil.users()
++suser = namedtuple('suser', ['name', 'terminal', 'host', 'started'])
++# psutil.net_connections()
++sconn = namedtuple('sconn', ['fd', 'family', 'type', 'laddr', 'raddr',
++                             'status', 'pid'])
++# psutil.net_if_addrs()
++snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast'])
++# psutil.net_if_stats()
++snicstats = namedtuple('snicstats', ['isup', 'duplex', 'speed', 'mtu'])
++
++
++# --- namedtuples for psutil.Process methods
++
++# psutil.Process.memory_info()
++pmem = namedtuple('pmem', ['rss', 'vms'])
++# psutil.Process.cpu_times()
++pcputimes = namedtuple('pcputimes', ['user', 'system'])
++# psutil.Process.open_files()
++popenfile = namedtuple('popenfile', ['path', 'fd'])
++# psutil.Process.threads()
++pthread = namedtuple('pthread', ['id', 'user_time', 'system_time'])
++# psutil.Process.uids()
++puids = namedtuple('puids', ['real', 'effective', 'saved'])
++# psutil.Process.gids()
++pgids = namedtuple('pgids', ['real', 'effective', 'saved'])
++# psutil.Process.io_counters()
++pio = namedtuple('pio', ['read_count', 'write_count',
++                         'read_bytes', 'write_bytes'])
++# psutil.Process.ionice()
++pionice = namedtuple('pionice', ['ioclass', 'value'])
++# psutil.Process.ctx_switches()
++pctxsw = namedtuple('pctxsw', ['voluntary', 'involuntary'])
++# psutil.Process.connections()
++pconn = namedtuple('pconn', ['fd', 'family', 'type', 'laddr', 'raddr',
++                             'status'])
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_compat.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_compat.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,268 +1,183 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """Module which provides compatibility with older Python versions."""
+ 
+-__all__ = ["PY3", "int", "long", "xrange", "exec_", "callable",
+-           "namedtuple", "property", "defaultdict"]
+-
++import collections
++import functools
+ import sys
+ 
++__all__ = ["PY3", "long", "xrange", "unicode", "callable", "lru_cache"]
+ 
+-# --- python 2/3 compatibility layer
+-
+-PY3 = sys.version_info >= (3,)
+-
+-try:
+-    import __builtin__
+-except ImportError:
+-    import builtins as __builtin__  # py3
++PY3 = sys.version_info[0] == 3
+ 
+ if PY3:
+-    int = int
+     long = int
+     xrange = range
+-    exec_ = getattr(__builtin__, "exec")
+-    print_ = getattr(__builtin__, "print")
++    unicode = str
+ else:
+-    int = int
+     long = long
+     xrange = xrange
+-
+-    def exec_(code, globs=None, locs=None):
+-        if globs is None:
+-            frame = _sys._getframe(1)
+-            globs = frame.f_globals
+-            if locs is None:
+-                locs = frame.f_locals
+-            del frame
+-        elif locs is None:
+-            locs = globs
+-        exec("""exec code in globs, locs""")
+-
+-    def print_(s):
+-        sys.stdout.write(s + '\n')
+-        sys.stdout.flush()
++    unicode = unicode
+ 
+ 
+ # removed in 3.0, reintroduced in 3.2
+ try:
+     callable = callable
+-except Exception:
++except NameError:
+     def callable(obj):
+-        for klass in type(obj).__mro__:
+-            if "__call__" in klass.__dict__:
+-                return True
+-        return False
++        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+ 
+ 
+ # --- stdlib additions
+ 
+-try:
+-    from collections import namedtuple
+-except ImportError:
+-    from operator import itemgetter as _itemgetter
+-    from keyword import iskeyword as _iskeyword
+-    import sys as _sys
+-
+-    def namedtuple(typename, field_names, verbose=False, rename=False):
+-        """A collections.namedtuple implementation written in Python
+-        to support Python versions < 2.6.
+-
+-        Taken from: http://code.activestate.com/recipes/500261/
+-        """
+-        # Parse and validate the field names.  Validation serves two
+-        # purposes, generating informative error messages and preventing
+-        # template injection attacks.
+-        if isinstance(field_names, basestring):
+-             # names separated by whitespace and/or commas
+-            field_names = field_names.replace(',', ' ').split()
+-        field_names = tuple(map(str, field_names))
+-        if rename:
+-            names = list(field_names)
+-            seen = set()
+-            for i, name in enumerate(names):
+-                if (not min(c.isalnum() or c=='_' for c in name) or _iskeyword(name)
+-                    or not name or name[0].isdigit() or name.startswith('_')
+-                    or name in seen):
+-                        names[i] = '_%d' % i
+-                seen.add(name)
+-            field_names = tuple(names)
+-        for name in (typename,) + field_names:
+-            if not min(c.isalnum() or c=='_' for c in name):
+-                raise ValueError('Type names and field names can only contain ' \
+-                                 'alphanumeric characters and underscores: %r'
+-                                 % name)
+-            if _iskeyword(name):
+-                raise ValueError('Type names and field names cannot be a keyword: %r' \
+-                                 % name)
+-            if name[0].isdigit():
+-                raise ValueError('Type names and field names cannot start with a ' \
+-                                 'number: %r' % name)
+-        seen_names = set()
+-        for name in field_names:
+-            if name.startswith('_') and not rename:
+-                raise ValueError('Field names cannot start with an underscore: %r'
+-                                 % name)
+-            if name in seen_names:
+-                raise ValueError('Encountered duplicate field name: %r' % name)
+-            seen_names.add(name)
+-
+-        # Create and fill-in the class template
+-        numfields = len(field_names)
+-        # tuple repr without parens or quotes
+-        argtxt = repr(field_names).replace("'", "")[1:-1]
+-        reprtxt = ', '.join('%s=%%r' % name for name in field_names)
+-        template = '''class %(typename)s(tuple):
+-        '%(typename)s(%(argtxt)s)' \n
+-        __slots__ = () \n
+-        _fields = %(field_names)r \n
+-        def __new__(_cls, %(argtxt)s):
+-            return _tuple.__new__(_cls, (%(argtxt)s)) \n
+-        @classmethod
+-        def _make(cls, iterable, new=tuple.__new__, len=len):
+-            'Make a new %(typename)s object from a sequence or iterable'
+-            result = new(cls, iterable)
+-            if len(result) != %(numfields)d:
+-                raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
+-            return result \n
+-        def __repr__(self):
+-            return '%(typename)s(%(reprtxt)s)' %% self \n
+-        def _asdict(self):
+-            'Return a new dict which maps field names to their values'
+-            return dict(zip(self._fields, self)) \n
+-        def _replace(_self, **kwds):
+-            'Return a new %(typename)s object replacing specified fields with new values'
+-            result = _self._make(map(kwds.pop, %(field_names)r, _self))
+-            if kwds:
+-                raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
+-            return result \n
+-        def __getnewargs__(self):
+-            return tuple(self) \n\n''' % locals()
+-        for i, name in enumerate(field_names):
+-            template += '        %s = _property(_itemgetter(%d))\n' % (name, i)
+-        if verbose:
+-            sys.stdout.write(template + '\n')
+-            sys.stdout.flush()
+-
+-        # Execute the template string in a temporary namespace
+-        namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
+-                         _property=property, _tuple=tuple)
+-        try:
+-            exec_(template, namespace)
+-        except SyntaxError:
+-            e = sys.exc_info()[1]
+-            raise SyntaxError(e.message + ':\n' + template)
+-        result = namespace[typename]
+-
+-        # For pickling to work, the __module__ variable needs to be set
+-        # to the frame where the named tuple is created.  Bypass this
+-        # step in enviroments where sys._getframe is not defined (Jython
+-        # for example) or sys._getframe is not defined for arguments
+-        # greater than 0 (IronPython).
+-        try:
+-            result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
+-        except (AttributeError, ValueError):
+-            pass
+-
+-        return result
+-
+-
+-# hack to support property.setter/deleter on python < 2.6
+-# http://docs.python.org/library/functions.html?highlight=property#property
+-if hasattr(property, 'setter'):
+-    property = property
+-else:
+-    class property(__builtin__.property):
+-        __metaclass__ = type
+-
+-        def __init__(self, fget, *args, **kwargs):
+-            super(property, self).__init__(fget, *args, **kwargs)
+-            self.__doc__ = fget.__doc__
+-
+-        def getter(self, method):
+-            return property(method, self.fset, self.fdel)
+ 
+-        def setter(self, method):
+-            return property(self.fget, method, self.fdel)
+-
+-        def deleter(self, method):
+-            return property(self.fget, self.fset, method)
+-
+-
+-# py 2.5 collections.defauldict
+-# Taken from:
+-# http://code.activestate.com/recipes/523034-emulate-collectionsdefaultdict/
+-# credits: Jason Kirtland
++# py 3.2 functools.lru_cache
++# Taken from: http://code.activestate.com/recipes/578078
++# Credit: Raymond Hettinger
+ try:
+-    from collections import defaultdict
++    from functools import lru_cache
+ except ImportError:
+-    class defaultdict(dict):
+-
+-        def __init__(self, default_factory=None, *a, **kw):
+-            if (default_factory is not None and
+-                not hasattr(default_factory, '__call__')):
+-                raise TypeError('first argument must be callable')
+-            dict.__init__(self, *a, **kw)
+-            self.default_factory = default_factory
+-
+-        def __getitem__(self, key):
+-            try:
+-                return dict.__getitem__(self, key)
+-            except KeyError:
+-                return self.__missing__(key)
+-
+-        def __missing__(self, key):
+-            if self.default_factory is None:
+-                raise KeyError(key)
+-            self[key] = value = self.default_factory()
+-            return value
+-
+-        def __reduce__(self):
+-            if self.default_factory is None:
+-                args = tuple()
++    try:
++        from threading import RLock
++    except ImportError:
++        from dummy_threading import RLock
++
++    _CacheInfo = collections.namedtuple(
++        "CacheInfo", ["hits", "misses", "maxsize", "currsize"])
++
++    class _HashedSeq(list):
++        __slots__ = 'hashvalue'
++
++        def __init__(self, tup, hash=hash):
++            self[:] = tup
++            self.hashvalue = hash(tup)
++
++        def __hash__(self):
++            return self.hashvalue
++
++    def _make_key(args, kwds, typed,
++                  kwd_mark=(object(), ),
++                  fasttypes=set((int, str, frozenset, type(None))),
++                  sorted=sorted, tuple=tuple, type=type, len=len):
++        key = args
++        if kwds:
++            sorted_items = sorted(kwds.items())
++            key += kwd_mark
++            for item in sorted_items:
++                key += item
++        if typed:
++            key += tuple(type(v) for v in args)
++            if kwds:
++                key += tuple(type(v) for k, v in sorted_items)
++        elif len(key) == 1 and type(key[0]) in fasttypes:
++            return key[0]
++        return _HashedSeq(key)
++
++    def lru_cache(maxsize=100, typed=False):
++        """Least-recently-used cache decorator, see:
++        http://docs.python.org/3/library/functools.html#functools.lru_cache
++        """
++        def decorating_function(user_function):
++            cache = dict()
++            stats = [0, 0]
++            HITS, MISSES = 0, 1
++            make_key = _make_key
++            cache_get = cache.get
++            _len = len
++            lock = RLock()
++            root = []
++            root[:] = [root, root, None, None]
++            nonlocal_root = [root]
++            PREV, NEXT, KEY, RESULT = 0, 1, 2, 3
++            if maxsize == 0:
++                def wrapper(*args, **kwds):
++                    result = user_function(*args, **kwds)
++                    stats[MISSES] += 1
++                    return result
++            elif maxsize is None:
++                def wrapper(*args, **kwds):
++                    key = make_key(args, kwds, typed)
++                    result = cache_get(key, root)
++                    if result is not root:
++                        stats[HITS] += 1
++                        return result
++                    result = user_function(*args, **kwds)
++                    cache[key] = result
++                    stats[MISSES] += 1
++                    return result
+             else:
+-                args = self.default_factory,
+-            return type(self), args, None, None, self.items()
+-
+-        def copy(self):
+-            return self.__copy__()
++                def wrapper(*args, **kwds):
++                    if kwds or typed:
++                        key = make_key(args, kwds, typed)
++                    else:
++                        key = args
++                    lock.acquire()
++                    try:
++                        link = cache_get(key)
++                        if link is not None:
++                            root, = nonlocal_root
++                            link_prev, link_next, key, result = link
++                            link_prev[NEXT] = link_next
++                            link_next[PREV] = link_prev
++                            last = root[PREV]
++                            last[NEXT] = root[PREV] = link
++                            link[PREV] = last
++                            link[NEXT] = root
++                            stats[HITS] += 1
++                            return result
++                    finally:
++                        lock.release()
++                    result = user_function(*args, **kwds)
++                    lock.acquire()
++                    try:
++                        root, = nonlocal_root
++                        if key in cache:
++                            pass
++                        elif _len(cache) >= maxsize:
++                            oldroot = root
++                            oldroot[KEY] = key
++                            oldroot[RESULT] = result
++                            root = nonlocal_root[0] = oldroot[NEXT]
++                            oldkey = root[KEY]
++                            root[KEY] = root[RESULT] = None
++                            del cache[oldkey]
++                            cache[key] = oldroot
++                        else:
++                            last = root[PREV]
++                            link = [last, root, key, result]
++                            last[NEXT] = root[PREV] = cache[key] = link
++                        stats[MISSES] += 1
++                    finally:
++                        lock.release()
++                    return result
++
++            def cache_info():
++                """Report cache statistics"""
++                lock.acquire()
++                try:
++                    return _CacheInfo(stats[HITS], stats[MISSES], maxsize,
++                                      len(cache))
++                finally:
++                    lock.release()
++
++            def cache_clear():
++                """Clear the cache and cache statistics"""
++                lock.acquire()
++                try:
++                    cache.clear()
++                    root = nonlocal_root[0]
++                    root[:] = [root, root, None, None]
++                    stats[:] = [0, 0]
++                finally:
++                    lock.release()
++
++            wrapper.__wrapped__ = user_function
++            wrapper.cache_info = cache_info
++            wrapper.cache_clear = cache_clear
++            return functools.update_wrapper(wrapper, user_function)
+ 
+-        def __copy__(self):
+-            return type(self)(self.default_factory, self)
+-
+-        def __deepcopy__(self, memo):
+-            import copy
+-            return type(self)(self.default_factory,
+-                              copy.deepcopy(self.items()))
+-
+-        def __repr__(self):
+-            return 'defaultdict(%s, %s)' % (self.default_factory,
+-                                            dict.__repr__(self))
+-
+-
+-# py 2.5 functools.wraps
+-try:
+-    from functools import wraps
+-except ImportError:
+-    def wraps(original):
+-        def inner(fn):
+-            # see functools.WRAPPER_ASSIGNMENTS
+-            for attribute in ['__module__',
+-                              '__name__',
+-                              '__doc__'
+-                              ]:
+-                setattr(fn, attribute, getattr(original, attribute))
+-            # see functools.WRAPPER_UPDATES
+-            for attribute in ['__dict__',
+-                              ]:
+-                if hasattr(fn, attribute):
+-                    getattr(fn, attribute).update(getattr(original, attribute))
+-                else:
+-                    setattr(fn, attribute,
+-                            getattr(original, attribute).copy())
+-            return fn
+-        return inner
++        return decorating_function
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_error.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_error.py	1969-12-31 16:00:00.000000000 -0800
+@@ -1,73 +0,0 @@
+-#!/usr/bin/env python
+-
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+-# Use of this source code is governed by a BSD-style license that can be
+-# found in the LICENSE file.
+-
+-"""psutil exception classes.
+-Not supposed to be used / imported directly.
+-Instead use psutil.NoSuchProcess, etc.
+-"""
+-
+-
+-class Error(Exception):
+-    """Base exception class. All other psutil exceptions inherit
+-    from this one.
+-    """
+-
+-class NoSuchProcess(Error):
+-    """Exception raised when a process with a certain PID doesn't
+-    or no longer exists (zombie).
+-    """
+-
+-    def __init__(self, pid, name=None, msg=None):
+-        self.pid = pid
+-        self.name = name
+-        self.msg = msg
+-        if msg is None:
+-            if name:
+-                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
+-            else:
+-                details = "(pid=%s)" % self.pid
+-            self.msg = "process no longer exists " + details
+-
+-    def __str__(self):
+-        return self.msg
+-
+-
+-class AccessDenied(Error):
+-    """Exception raised when permission to perform an action is denied."""
+-
+-    def __init__(self, pid=None, name=None, msg=None):
+-        self.pid = pid
+-        self.name = name
+-        self.msg = msg
+-        if msg is None:
+-            if (pid is not None) and (name is not None):
+-                self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+-            elif (pid is not None):
+-                self.msg = "(pid=%s)" % self.pid
+-            else:
+-                self.msg = ""
+-
+-    def __str__(self):
+-        return self.msg
+-
+-
+-class TimeoutExpired(Error):
+-    """Raised on Process.wait(timeout) if timeout expires and process
+-    is still alive.
+-    """
+-
+-    def __init__(self, pid=None, name=None):
+-        self.pid = pid
+-        self.name = name
+-        if (pid is not None) and (name is not None):
+-            self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+-        elif (pid is not None):
+-            self.msg = "(pid=%s)" % self.pid
+-        else:
+-            self.msg = ""
+-
+-    def __str__(self):
+-        return self.msg
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psbsd.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psbsd.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,202 +1,288 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """FreeBSD platform implementation."""
+ 
+ import errno
++import functools
+ import os
+-import sys
+-import warnings
++import xml.etree.ElementTree as ET
++from collections import namedtuple
++
++from . import _common
++from . import _psposix
++from . import _psutil_bsd as cext
++from . import _psutil_posix as cext_posix
++from ._common import conn_tmap, usage_percent, sockfam_to_enum
++from ._common import socktype_to_enum
+ 
+-import _psutil_bsd
+-import _psutil_posix
+-from psutil import _psposix
+-from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+-from psutil._compat import namedtuple, wraps
+-from psutil._common import *
+ 
+ __extra__all__ = []
+ 
+ # --- constants
+ 
+-# Since these constants get determined at import time we do not want to
+-# crash immediately; instead we'll set them to None and most likely
+-# we'll crash later as they're used for determining process CPU stats
+-# and creation_time
+-try:
+-    NUM_CPUS = _psutil_bsd.get_num_cpus()
+-except Exception:
+-    NUM_CPUS = None
+-    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+-try:
+-    TOTAL_PHYMEM = _psutil_bsd.get_virtual_mem()[0]
+-except Exception:
+-    TOTAL_PHYMEM = None
+-    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+-try:
+-    BOOT_TIME = _psutil_bsd.get_system_boot_time()
+-except Exception:
+-    BOOT_TIME = None
+-    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+-
+-
+-_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+-_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle irq')
+-
+-# --- public functions
+-
+-get_system_boot_time = _psutil_bsd.get_system_boot_time
+-
+-nt_virtmem_info = namedtuple('vmem', ' '.join([
+-    # all platforms
+-    'total', 'available', 'percent', 'used', 'free',
+-    # FreeBSD specific
+-    'active',
+-    'inactive',
+-    'buffers',
+-    'cached',
+-    'shared',
+-    'wired']))
++PROC_STATUSES = {
++    cext.SSTOP: _common.STATUS_STOPPED,
++    cext.SSLEEP: _common.STATUS_SLEEPING,
++    cext.SRUN: _common.STATUS_RUNNING,
++    cext.SIDL: _common.STATUS_IDLE,
++    cext.SWAIT: _common.STATUS_WAITING,
++    cext.SLOCK: _common.STATUS_LOCKED,
++    cext.SZOMB: _common.STATUS_ZOMBIE,
++}
++
++TCP_STATUSES = {
++    cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
++    cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
++    cext.TCPS_SYN_RECEIVED: _common.CONN_SYN_RECV,
++    cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
++    cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
++    cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
++    cext.TCPS_CLOSED: _common.CONN_CLOSE,
++    cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
++    cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
++    cext.TCPS_LISTEN: _common.CONN_LISTEN,
++    cext.TCPS_CLOSING: _common.CONN_CLOSING,
++    cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
++}
++
++PAGESIZE = os.sysconf("SC_PAGE_SIZE")
++AF_LINK = cext_posix.AF_LINK
++
++# extend base mem ntuple with BSD-specific memory metrics
++svmem = namedtuple(
++    'svmem', ['total', 'available', 'percent', 'used', 'free',
++              'active', 'inactive', 'buffers', 'cached', 'shared', 'wired'])
++scputimes = namedtuple(
++    'scputimes', ['user', 'nice', 'system', 'idle', 'irq'])
++pextmem = namedtuple('pextmem', ['rss', 'vms', 'text', 'data', 'stack'])
++pmmap_grouped = namedtuple(
++    'pmmap_grouped', 'path rss, private, ref_count, shadow_count')
++pmmap_ext = namedtuple(
++    'pmmap_ext', 'addr, perms path rss, private, ref_count, shadow_count')
++
++# set later from __init__.py
++NoSuchProcess = None
++ZombieProcess = None
++AccessDenied = None
++TimeoutExpired = None
++
+ 
+ def virtual_memory():
+-    """System virtual memory as a namedutple."""
+-    mem =  _psutil_bsd.get_virtual_mem()
++    """System virtual memory as a namedtuple."""
++    mem = cext.virtual_mem()
+     total, free, active, inactive, wired, cached, buffers, shared = mem
+     avail = inactive + cached + free
+-    used =  active + wired + cached
++    used = active + wired + cached
+     percent = usage_percent((total - avail), total, _round=1)
+-    return nt_virtmem_info(total, avail, percent, used, free,
+-                           active, inactive, buffers, cached, shared, wired)
++    return svmem(total, avail, percent, used, free,
++                 active, inactive, buffers, cached, shared, wired)
++
+ 
+ def swap_memory():
+     """System swap memory as (total, used, free, sin, sout) namedtuple."""
+-    total, used, free, sin, sout = \
+-        [x * _PAGESIZE for x in _psutil_bsd.get_swap_mem()]
++    total, used, free, sin, sout = [x * PAGESIZE for x in cext.swap_mem()]
+     percent = usage_percent(used, total, _round=1)
+-    return nt_swapmeminfo(total, used, free, percent, sin, sout)
++    return _common.sswap(total, used, free, percent, sin, sout)
+ 
+-def get_system_cpu_times():
+-    """Return system per-CPU times as a named tuple"""
+-    user, nice, system, idle, irq = _psutil_bsd.get_system_cpu_times()
+-    return _cputimes_ntuple(user, nice, system, idle, irq)
+-
+-def get_system_per_cpu_times():
+-    """Return system CPU times as a named tuple"""
+-    ret = []
+-    for cpu_t in _psutil_bsd.get_system_per_cpu_times():
+-        user, nice, system, idle, irq = cpu_t
+-        item = _cputimes_ntuple(user, nice, system, idle, irq)
+-        ret.append(item)
+-    return ret
+ 
+-# XXX
+-# Ok, this is very dirty.
+-# On FreeBSD < 8 we cannot gather per-cpu information, see:
+-# http://code.google.com/p/psutil/issues/detail?id=226
+-# If NUM_CPUS > 1, on first call we return single cpu times to avoid a
+-# crash at psutil import time.
+-# Next calls will fail with NotImplementedError
+-if not hasattr(_psutil_bsd, "get_system_per_cpu_times"):
+-    def get_system_per_cpu_times():
+-        if NUM_CPUS == 1:
+-            return [get_system_cpu_times]
+-        if get_system_per_cpu_times.__called__:
++def cpu_times():
++    """Return system per-CPU times as a namedtuple"""
++    user, nice, system, idle, irq = cext.cpu_times()
++    return scputimes(user, nice, system, idle, irq)
++
++
++if hasattr(cext, "per_cpu_times"):
++    def per_cpu_times():
++        """Return system CPU times as a namedtuple"""
++        ret = []
++        for cpu_t in cext.per_cpu_times():
++            user, nice, system, idle, irq = cpu_t
++            item = scputimes(user, nice, system, idle, irq)
++            ret.append(item)
++        return ret
++else:
++    # XXX
++    # Ok, this is very dirty.
++    # On FreeBSD < 8 we cannot gather per-cpu information, see:
++    # https://github.com/giampaolo/psutil/issues/226
++    # If num cpus > 1, on first call we return single cpu times to avoid a
++    # crash at psutil import time.
++    # Next calls will fail with NotImplementedError
++    def per_cpu_times():
++        if cpu_count_logical() == 1:
++            return [cpu_times()]
++        if per_cpu_times.__called__:
+             raise NotImplementedError("supported only starting from FreeBSD 8")
+-        get_system_per_cpu_times.__called__ = True
+-        return [get_system_cpu_times]
+-get_system_per_cpu_times.__called__ = False
++        per_cpu_times.__called__ = True
++        return [cpu_times()]
++
++    per_cpu_times.__called__ = False
++
++
++def cpu_count_logical():
++    """Return the number of logical CPUs in the system."""
++    return cext.cpu_count_logical()
++
++
++def cpu_count_physical():
++    """Return the number of physical CPUs in the system."""
++    # From the C module we'll get an XML string similar to this:
++    # http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html
++    # We may get None in case "sysctl kern.sched.topology_spec"
++    # is not supported on this BSD version, in which case we'll mimic
++    # os.cpu_count() and return None.
++    ret = None
++    s = cext.cpu_count_phys()
++    if s is not None:
++        # get rid of padding chars appended at the end of the string
++        index = s.rfind("</groups>")
++        if index != -1:
++            s = s[:index + 9]
++            root = ET.fromstring(s)
++            try:
++                ret = len(root.findall('group/children/group/cpu')) or None
++            finally:
++                # needed otherwise it will memleak
++                root.clear()
++    if not ret:
++        # If logical CPUs are 1 it's obvious we'll have only 1
++        # physical CPU.
++        if cpu_count_logical() == 1:
++            return 1
++    return ret
++
++
++def boot_time():
++    """The system boot time expressed in seconds since the epoch."""
++    return cext.boot_time()
++
+ 
+ def disk_partitions(all=False):
+     retlist = []
+-    partitions = _psutil_bsd.get_disk_partitions()
++    partitions = cext.disk_partitions()
+     for partition in partitions:
+         device, mountpoint, fstype, opts = partition
+         if device == 'none':
+             device = ''
+         if not all:
+-            if not os.path.isabs(device) \
+-            or not os.path.exists(device):
++            if not os.path.isabs(device) or not os.path.exists(device):
+                 continue
+-        ntuple = nt_partition(device, mountpoint, fstype, opts)
++        ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
+         retlist.append(ntuple)
+     return retlist
+ 
+-def get_system_users():
++
++def users():
+     retlist = []
+-    rawlist = _psutil_bsd.get_system_users()
++    rawlist = cext.users()
+     for item in rawlist:
+         user, tty, hostname, tstamp = item
+         if tty == '~':
+             continue  # reboot or shutdown
+-        nt = nt_user(user, tty or None, hostname, tstamp)
++        nt = _common.suser(user, tty or None, hostname, tstamp)
+         retlist.append(nt)
+     return retlist
+ 
+-get_pid_list = _psutil_bsd.get_pid_list
++
++def net_connections(kind):
++    if kind not in _common.conn_tmap:
++        raise ValueError("invalid %r kind argument; choose between %s"
++                         % (kind, ', '.join([repr(x) for x in conn_tmap])))
++    families, types = conn_tmap[kind]
++    ret = set()
++    rawlist = cext.net_connections()
++    for item in rawlist:
++        fd, fam, type, laddr, raddr, status, pid = item
++        # TODO: apply filter at C level
++        if fam in families and type in types:
++            try:
++                status = TCP_STATUSES[status]
++            except KeyError:
++                # XXX: Not sure why this happens. I saw this occurring
++                # with IPv6 sockets opened by 'vim'. Those sockets
++                # have a very short lifetime so maybe the kernel
++                # can't initialize their status?
++                status = TCP_STATUSES[cext.PSUTIL_CONN_NONE]
++            fam = sockfam_to_enum(fam)
++            type = socktype_to_enum(type)
++            nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid)
++            ret.add(nt)
++    return list(ret)
++
++
++def net_if_stats():
++    """Get NIC stats (isup, duplex, speed, mtu)."""
++    names = net_io_counters().keys()
++    ret = {}
++    for name in names:
++        isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
++        if hasattr(_common, 'NicDuplex'):
++            duplex = _common.NicDuplex(duplex)
++        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
++    return ret
++
++
++pids = cext.pids
+ pid_exists = _psposix.pid_exists
+-get_disk_usage = _psposix.get_disk_usage
+-network_io_counters = _psutil_bsd.get_network_io_counters
+-disk_io_counters = _psutil_bsd.get_disk_io_counters
++disk_usage = _psposix.disk_usage
++net_io_counters = cext.net_io_counters
++disk_io_counters = cext.disk_io_counters
++net_if_addrs = cext_posix.net_if_addrs
+ 
+ 
+ def wrap_exceptions(fun):
+     """Decorator which translates bare OSError exceptions into
+     NoSuchProcess and AccessDenied.
+     """
+-    @wraps(fun)
++    @functools.wraps(fun)
+     def wrapper(self, *args, **kwargs):
+         try:
+             return fun(self, *args, **kwargs)
+-        except OSError:
+-            err = sys.exc_info()[1]
++        except OSError as err:
++            # support for private module import
++            if (NoSuchProcess is None or AccessDenied is None or
++                    ZombieProcess is None):
++                raise
+             if err.errno == errno.ESRCH:
+-                raise NoSuchProcess(self.pid, self._process_name)
++                if not pid_exists(self.pid):
++                    raise NoSuchProcess(self.pid, self._name)
++                else:
++                    raise ZombieProcess(self.pid, self._name, self._ppid)
+             if err.errno in (errno.EPERM, errno.EACCES):
+-                raise AccessDenied(self.pid, self._process_name)
++                raise AccessDenied(self.pid, self._name)
+             raise
+     return wrapper
+ 
+-_status_map = {
+-    _psutil_bsd.SSTOP : STATUS_STOPPED,
+-    _psutil_bsd.SSLEEP : STATUS_SLEEPING,
+-    _psutil_bsd.SRUN : STATUS_RUNNING,
+-    _psutil_bsd.SIDL : STATUS_IDLE,
+-    _psutil_bsd.SWAIT : STATUS_WAITING,
+-    _psutil_bsd.SLOCK : STATUS_LOCKED,
+-    _psutil_bsd.SZOMB : STATUS_ZOMBIE,
+-}
+-
+ 
+ class Process(object):
+     """Wrapper class around underlying C implementation."""
+ 
+-    __slots__ = ["pid", "_process_name"]
++    __slots__ = ["pid", "_name", "_ppid"]
+ 
+     def __init__(self, pid):
+         self.pid = pid
+-        self._process_name = None
++        self._name = None
++        self._ppid = None
+ 
+     @wrap_exceptions
+-    def get_process_name(self):
+-        """Return process name as a string of limited len (15)."""
+-        return _psutil_bsd.get_process_name(self.pid)
++    def name(self):
++        return cext.proc_name(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_exe(self):
+-        """Return process executable pathname."""
+-        return _psutil_bsd.get_process_exe(self.pid)
++    def exe(self):
++        return cext.proc_exe(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_cmdline(self):
+-        """Return process cmdline as a list of arguments."""
+-        return _psutil_bsd.get_process_cmdline(self.pid)
++    def cmdline(self):
++        return cext.proc_cmdline(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_terminal(self):
+-        tty_nr = _psutil_bsd.get_process_tty_nr(self.pid)
++    def terminal(self):
++        tty_nr = cext.proc_tty_nr(self.pid)
+         tmap = _psposix._get_terminal_map()
+         try:
+             return tmap[tty_nr]
+@@ -204,144 +290,166 @@
+             return None
+ 
+     @wrap_exceptions
+-    def get_process_ppid(self):
+-        """Return process parent pid."""
+-        return _psutil_bsd.get_process_ppid(self.pid)
+-
+-    # XXX - available on FreeBSD >= 8 only
+-    if hasattr(_psutil_bsd, "get_process_cwd"):
+-        @wrap_exceptions
+-        def get_process_cwd(self):
+-            """Return process current working directory."""
+-            # sometimes we get an empty string, in which case we turn
+-            # it into None
+-            return _psutil_bsd.get_process_cwd(self.pid) or None
+-
+-    @wrap_exceptions
+-    def get_process_uids(self):
+-        """Return real, effective and saved user ids."""
+-        real, effective, saved = _psutil_bsd.get_process_uids(self.pid)
+-        return nt_uids(real, effective, saved)
++    def ppid(self):
++        return cext.proc_ppid(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_gids(self):
+-        """Return real, effective and saved group ids."""
+-        real, effective, saved = _psutil_bsd.get_process_gids(self.pid)
+-        return nt_gids(real, effective, saved)
++    def uids(self):
++        real, effective, saved = cext.proc_uids(self.pid)
++        return _common.puids(real, effective, saved)
+ 
+     @wrap_exceptions
+-    def get_cpu_times(self):
+-        """return a tuple containing process user/kernel time."""
+-        user, system = _psutil_bsd.get_process_cpu_times(self.pid)
+-        return nt_cputimes(user, system)
++    def gids(self):
++        real, effective, saved = cext.proc_gids(self.pid)
++        return _common.pgids(real, effective, saved)
+ 
+     @wrap_exceptions
+-    def get_memory_info(self):
+-        """Return a tuple with the process' RSS and VMS size."""
+-        rss, vms = _psutil_bsd.get_process_memory_info(self.pid)[:2]
+-        return nt_meminfo(rss, vms)
+-
+-    _nt_ext_mem = namedtuple('meminfo', 'rss vms text data stack')
++    def cpu_times(self):
++        user, system = cext.proc_cpu_times(self.pid)
++        return _common.pcputimes(user, system)
+ 
+     @wrap_exceptions
+-    def get_ext_memory_info(self):
+-        return self._nt_ext_mem(*_psutil_bsd.get_process_memory_info(self.pid))
++    def memory_info(self):
++        rss, vms = cext.proc_memory_info(self.pid)[:2]
++        return _common.pmem(rss, vms)
+ 
+     @wrap_exceptions
+-    def get_process_create_time(self):
+-        """Return the start time of the process as a number of seconds since
+-        the epoch."""
+-        return _psutil_bsd.get_process_create_time(self.pid)
++    def memory_info_ex(self):
++        return pextmem(*cext.proc_memory_info(self.pid))
+ 
+     @wrap_exceptions
+-    def get_process_num_threads(self):
+-        """Return the number of threads belonging to the process."""
+-        return _psutil_bsd.get_process_num_threads(self.pid)
++    def create_time(self):
++        return cext.proc_create_time(self.pid)
+ 
+     @wrap_exceptions
+-    def get_num_ctx_switches(self):
+-        return nt_ctxsw(*_psutil_bsd.get_process_num_ctx_switches(self.pid))
++    def num_threads(self):
++        return cext.proc_num_threads(self.pid)
+ 
+     @wrap_exceptions
+-    def get_num_fds(self):
+-        """Return the number of file descriptors opened by this process."""
+-        return _psutil_bsd.get_process_num_fds(self.pid)
++    def num_ctx_switches(self):
++        return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
+ 
+     @wrap_exceptions
+-    def get_process_threads(self):
+-        """Return the number of threads belonging to the process."""
+-        rawlist = _psutil_bsd.get_process_threads(self.pid)
++    def threads(self):
++        rawlist = cext.proc_threads(self.pid)
+         retlist = []
+         for thread_id, utime, stime in rawlist:
+-            ntuple = nt_thread(thread_id, utime, stime)
++            ntuple = _common.pthread(thread_id, utime, stime)
+             retlist.append(ntuple)
+         return retlist
+ 
+     @wrap_exceptions
+-    def get_open_files(self):
+-        """Return files opened by process as a list of namedtuples."""
+-        # XXX - C implementation available on FreeBSD >= 8 only
+-        # else fallback on lsof parser
+-        if hasattr(_psutil_bsd, "get_process_open_files"):
+-            rawlist = _psutil_bsd.get_process_open_files(self.pid)
+-            return [nt_openfile(path, fd) for path, fd in rawlist]
+-        else:
+-            lsof = _psposix.LsofParser(self.pid, self._process_name)
+-            return lsof.get_process_open_files()
+-
+-    @wrap_exceptions
+-    def get_connections(self, kind='inet'):
+-        """Return etwork connections opened by a process as a list of
+-        namedtuples.
+-        """
++    def connections(self, kind='inet'):
+         if kind not in conn_tmap:
+             raise ValueError("invalid %r kind argument; choose between %s"
+                              % (kind, ', '.join([repr(x) for x in conn_tmap])))
+         families, types = conn_tmap[kind]
+-        ret = _psutil_bsd.get_process_connections(self.pid, families, types)
+-        return [nt_connection(*conn) for conn in ret]
++        rawlist = cext.proc_connections(self.pid, families, types)
++        ret = []
++        for item in rawlist:
++            fd, fam, type, laddr, raddr, status = item
++            fam = sockfam_to_enum(fam)
++            type = socktype_to_enum(type)
++            status = TCP_STATUSES[status]
++            nt = _common.pconn(fd, fam, type, laddr, raddr, status)
++            ret.append(nt)
++        return ret
+ 
+     @wrap_exceptions
+-    def process_wait(self, timeout=None):
++    def wait(self, timeout=None):
+         try:
+             return _psposix.wait_pid(self.pid, timeout)
+-        except TimeoutExpired:
+-            raise TimeoutExpired(self.pid, self._process_name)
++        except _psposix.TimeoutExpired:
++            # support for private module import
++            if TimeoutExpired is None:
++                raise
++            raise TimeoutExpired(timeout, self.pid, self._name)
+ 
+     @wrap_exceptions
+-    def get_process_nice(self):
+-        return _psutil_posix.getpriority(self.pid)
++    def nice_get(self):
++        return cext_posix.getpriority(self.pid)
+ 
+     @wrap_exceptions
+-    def set_process_nice(self, value):
+-        return _psutil_posix.setpriority(self.pid, value)
++    def nice_set(self, value):
++        return cext_posix.setpriority(self.pid, value)
+ 
+     @wrap_exceptions
+-    def get_process_status(self):
+-        code = _psutil_bsd.get_process_status(self.pid)
+-        if code in _status_map:
+-            return _status_map[code]
+-        return constant(-1, "?")
++    def status(self):
++        code = cext.proc_status(self.pid)
++        if code in PROC_STATUSES:
++            return PROC_STATUSES[code]
++        # XXX is this legit? will we even ever get here?
++        return "?"
+ 
+     @wrap_exceptions
+-    def get_process_io_counters(self):
+-        rc, wc, rb, wb = _psutil_bsd.get_process_io_counters(self.pid)
+-        return nt_io(rc, wc, rb, wb)
++    def io_counters(self):
++        rc, wc, rb, wb = cext.proc_io_counters(self.pid)
++        return _common.pio(rc, wc, rb, wb)
+ 
+-    nt_mmap_grouped = namedtuple('mmap',
+-        'path rss, private, ref_count, shadow_count')
+-    nt_mmap_ext = namedtuple('mmap',
+-        'addr, perms path rss, private, ref_count, shadow_count')
++    nt_mmap_grouped = namedtuple(
++        'mmap', 'path rss, private, ref_count, shadow_count')
++    nt_mmap_ext = namedtuple(
++        'mmap', 'addr, perms path rss, private, ref_count, shadow_count')
+ 
+-    @wrap_exceptions
+-    def get_memory_maps(self):
+-        return _psutil_bsd.get_process_memory_maps(self.pid)
++    # FreeBSD < 8 does not support functions based on kinfo_getfile()
++    # and kinfo_getvmmap()
++    if hasattr(cext, 'proc_open_files'):
+ 
+-    # FreeBSD < 8 does not support kinfo_getfile() and kinfo_getvmmap()
+-    if not hasattr(_psutil_bsd, 'get_process_open_files'):
++        @wrap_exceptions
++        def open_files(self):
++            """Return files opened by process as a list of namedtuples."""
++            rawlist = cext.proc_open_files(self.pid)
++            return [_common.popenfile(path, fd) for path, fd in rawlist]
++
++        @wrap_exceptions
++        def cwd(self):
++            """Return process current working directory."""
++            # sometimes we get an empty string, in which case we turn
++            # it into None
++            return cext.proc_cwd(self.pid) or None
++
++        @wrap_exceptions
++        def memory_maps(self):
++            return cext.proc_memory_maps(self.pid)
++
++        @wrap_exceptions
++        def num_fds(self):
++            """Return the number of file descriptors opened by this process."""
++            return cext.proc_num_fds(self.pid)
++
++    else:
+         def _not_implemented(self):
+             raise NotImplementedError("supported only starting from FreeBSD 8")
+-        get_open_files = _not_implemented
+-        get_process_cwd = _not_implemented
+-        get_memory_maps = _not_implemented
+-        get_num_fds = _not_implemented
++
++        open_files = _not_implemented
++        proc_cwd = _not_implemented
++        memory_maps = _not_implemented
++        num_fds = _not_implemented
++
++    @wrap_exceptions
++    def cpu_affinity_get(self):
++        return cext.proc_cpu_affinity_get(self.pid)
++
++    @wrap_exceptions
++    def cpu_affinity_set(self, cpus):
++        # Pre-emptively check if CPUs are valid because the C
++        # function has a weird behavior in case of invalid CPUs,
++        # see: https://github.com/giampaolo/psutil/issues/586
++        allcpus = tuple(range(len(per_cpu_times())))
++        for cpu in cpus:
++            if cpu not in allcpus:
++                raise ValueError("invalid CPU #%i (choose between %s)"
++                                 % (cpu, allcpus))
++        try:
++            cext.proc_cpu_affinity_set(self.pid, cpus)
++        except OSError as err:
++            # 'man cpuset_setaffinity' about EDEADLK:
++            # <<the call would leave a thread without a valid CPU to run
++            # on because the set does not overlap with the thread's
++            # anonymous mask>>
++            if err.errno in (errno.EINVAL, errno.EDEADLK):
++                for cpu in cpus:
++                    if cpu not in allcpus:
++                        raise ValueError("invalid CPU #%i (choose between %s)"
++                                         % (cpu, allcpus))
++            raise
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_pslinux.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_pslinux.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,6 +1,6 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -8,302 +8,304 @@
+ 
+ from __future__ import division
+ 
+-import os
++import base64
+ import errno
++import functools
++import os
++import re
+ import socket
+ import struct
+ import sys
+-import base64
+-import re
+ import warnings
++from collections import namedtuple, defaultdict
++
++from . import _common
++from . import _psposix
++from . import _psutil_linux as cext
++from . import _psutil_posix as cext_posix
++from ._common import isfile_strict, usage_percent
++from ._common import NIC_DUPLEX_FULL, NIC_DUPLEX_HALF, NIC_DUPLEX_UNKNOWN
++from ._compat import PY3
++
++if sys.version_info >= (3, 4):
++    import enum
++else:
++    enum = None
+ 
+-import _psutil_posix
+-import _psutil_linux
+-from psutil import _psposix
+-from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+-from psutil._common import *
+-from psutil._compat import PY3, xrange, long, namedtuple, wraps
+ 
+ __extra__all__ = [
++    # io prio constants
+     "IOPRIO_CLASS_NONE", "IOPRIO_CLASS_RT", "IOPRIO_CLASS_BE",
+     "IOPRIO_CLASS_IDLE",
+-    "phymem_buffers", "cached_phymem"]
++    # connection status constants
++    "CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1",
++    "CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
++    "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", ]
++
++# --- constants
++
++HAS_PRLIMIT = hasattr(cext, "linux_prlimit")
++
++# RLIMIT_* constants, not guaranteed to be present on all kernels
++if HAS_PRLIMIT:
++    for name in dir(cext):
++        if name.startswith('RLIM'):
++            __extra__all__.append(name)
+ 
++# Number of clock ticks per second
++CLOCK_TICKS = os.sysconf("SC_CLK_TCK")
++PAGESIZE = os.sysconf("SC_PAGE_SIZE")
++BOOT_TIME = None  # set later
++DEFAULT_ENCODING = sys.getdefaultencoding()
++if enum is None:
++    AF_LINK = socket.AF_PACKET
++else:
++    AddressFamily = enum.IntEnum('AddressFamily',
++                                 {'AF_LINK': socket.AF_PACKET})
++    AF_LINK = AddressFamily.AF_LINK
+ 
+-def get_system_boot_time():
+-    """Return the system boot time expressed in seconds since the epoch."""
+-    f = open('/proc/stat', 'r')
+-    try:
+-        for line in f:
+-            if line.startswith('btime'):
+-                return float(line.strip().split()[1])
+-        raise RuntimeError("line 'btime' not found")
+-    finally:
+-        f.close()
++# ioprio_* constants http://linux.die.net/man/2/ioprio_get
++if enum is None:
++    IOPRIO_CLASS_NONE = 0
++    IOPRIO_CLASS_RT = 1
++    IOPRIO_CLASS_BE = 2
++    IOPRIO_CLASS_IDLE = 3
++else:
++    class IOPriority(enum.IntEnum):
++        IOPRIO_CLASS_NONE = 0
++        IOPRIO_CLASS_RT = 1
++        IOPRIO_CLASS_BE = 2
++        IOPRIO_CLASS_IDLE = 3
+ 
+-def _get_num_cpus():
+-    """Return the number of CPUs on the system"""
+-    try:
+-        return os.sysconf("SC_NPROCESSORS_ONLN")
+-    except ValueError:
+-        # as a second fallback we try to parse /proc/cpuinfo
+-        num = 0
+-        f = open('/proc/cpuinfo', 'r')
+-        try:
+-            lines = f.readlines()
+-        finally:
+-            f.close()
+-        for line in lines:
+-            if line.lower().startswith('processor'):
+-                num += 1
+-
+-    # unknown format (e.g. amrel/sparc architectures), see:
+-    # http://code.google.com/p/psutil/issues/detail?id=200
+-    # try to parse /proc/stat as a last resort
+-    if num == 0:
+-        f = open('/proc/stat', 'r')
+-        try:
+-            lines = f.readlines()
+-        finally:
+-            f.close()
+-        search = re.compile('cpu\d')
+-        for line in lines:
+-            line = line.split(' ')[0]
+-            if search.match(line):
+-                num += 1
+-
+-    if num == 0:
+-        raise RuntimeError("couldn't determine platform's NUM_CPUS")
+-    return num
++    globals().update(IOPriority.__members__)
++
++# taken from /fs/proc/array.c
++PROC_STATUSES = {
++    "R": _common.STATUS_RUNNING,
++    "S": _common.STATUS_SLEEPING,
++    "D": _common.STATUS_DISK_SLEEP,
++    "T": _common.STATUS_STOPPED,
++    "t": _common.STATUS_TRACING_STOP,
++    "Z": _common.STATUS_ZOMBIE,
++    "X": _common.STATUS_DEAD,
++    "x": _common.STATUS_DEAD,
++    "K": _common.STATUS_WAKE_KILL,
++    "W": _common.STATUS_WAKING
++}
+ 
++# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
++TCP_STATUSES = {
++    "01": _common.CONN_ESTABLISHED,
++    "02": _common.CONN_SYN_SENT,
++    "03": _common.CONN_SYN_RECV,
++    "04": _common.CONN_FIN_WAIT1,
++    "05": _common.CONN_FIN_WAIT2,
++    "06": _common.CONN_TIME_WAIT,
++    "07": _common.CONN_CLOSE,
++    "08": _common.CONN_CLOSE_WAIT,
++    "09": _common.CONN_LAST_ACK,
++    "0A": _common.CONN_LISTEN,
++    "0B": _common.CONN_CLOSING
++}
++
++# set later from __init__.py
++NoSuchProcess = None
++ZombieProcess = None
++AccessDenied = None
++TimeoutExpired = None
++
++
++# --- named tuples
++
++def _get_cputimes_fields():
++    """Return a namedtuple of variable fields depending on the
++    CPU times available on this Linux kernel version which may be:
++    (user, nice, system, idle, iowait, irq, softirq, [steal, [guest,
++     [guest_nice]]])
++    """
++    with open('/proc/stat', 'rb') as f:
++        values = f.readline().split()[1:]
++    fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
++    vlen = len(values)
++    if vlen >= 8:
++        # Linux >= 2.6.11
++        fields.append('steal')
++    if vlen >= 9:
++        # Linux >= 2.6.24
++        fields.append('guest')
++    if vlen >= 10:
++        # Linux >= 3.2.0
++        fields.append('guest_nice')
++    return fields
+ 
+-# Number of clock ticks per second
+-_CLOCK_TICKS = os.sysconf("SC_CLK_TCK")
+-_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+ 
+-# Since these constants get determined at import time we do not want to
+-# crash immediately; instead we'll set them to None and most likely
+-# we'll crash later as they're used for determining process CPU stats
+-# and creation_time
+-try:
+-    BOOT_TIME = get_system_boot_time()
+-except Exception:
+-    BOOT_TIME = None
+-    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+-try:
+-    NUM_CPUS = _get_num_cpus()
+-except Exception:
+-    NUM_CPUS = None
+-    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+-try:
+-    TOTAL_PHYMEM = _psutil_linux.get_sysinfo()[0]
+-except Exception:
+-    TOTAL_PHYMEM = None
+-    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
++scputimes = namedtuple('scputimes', _get_cputimes_fields())
+ 
++svmem = namedtuple(
++    'svmem', ['total', 'available', 'percent', 'used', 'free',
++              'active', 'inactive', 'buffers', 'cached'])
+ 
+-# ioprio_* constants http://linux.die.net/man/2/ioprio_get
+-IOPRIO_CLASS_NONE = 0
+-IOPRIO_CLASS_RT = 1
+-IOPRIO_CLASS_BE = 2
+-IOPRIO_CLASS_IDLE = 3
++pextmem = namedtuple('pextmem', 'rss vms shared text lib data dirty')
+ 
+-# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
+-_TCP_STATES_TABLE = {"01" : "ESTABLISHED",
+-                     "02" : "SYN_SENT",
+-                     "03" : "SYN_RECV",
+-                     "04" : "FIN_WAIT1",
+-                     "05" : "FIN_WAIT2",
+-                     "06" : "TIME_WAIT",
+-                     "07" : "CLOSE",
+-                     "08" : "CLOSE_WAIT",
+-                     "09" : "LAST_ACK",
+-                     "0A" : "LISTEN",
+-                     "0B" : "CLOSING"
+-                     }
+-
+-# --- system memory functions
+-
+-nt_virtmem_info = namedtuple('vmem', ' '.join([
+-    # all platforms
+-    'total', 'available', 'percent', 'used', 'free',
+-    # linux specific
+-    'active',
+-    'inactive',
+-    'buffers',
+-    'cached']))
++pmmap_grouped = namedtuple(
++    'pmmap_grouped', ['path', 'rss', 'size', 'pss', 'shared_clean',
++                      'shared_dirty', 'private_clean', 'private_dirty',
++                      'referenced', 'anonymous', 'swap'])
++
++pmmap_ext = namedtuple(
++    'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
++
++
++# --- system memory
+ 
+ def virtual_memory():
+-    total, free, buffers, shared, _, _ = _psutil_linux.get_sysinfo()
++    total, free, buffers, shared, _, _ = cext.linux_sysinfo()
+     cached = active = inactive = None
+-    f = open('/proc/meminfo', 'r')
+-    try:
++    with open('/proc/meminfo', 'rb') as f:
+         for line in f:
+-            if line.startswith('Cached:'):
++            if line.startswith(b"Cached:"):
+                 cached = int(line.split()[1]) * 1024
+-            elif line.startswith('Active:'):
++            elif line.startswith(b"Active:"):
+                 active = int(line.split()[1]) * 1024
+-            elif line.startswith('Inactive:'):
++            elif line.startswith(b"Inactive:"):
+                 inactive = int(line.split()[1]) * 1024
+-            if cached is not None \
+-            and active is not None \
+-            and inactive is not None:
++            if (cached is not None and
++                    active is not None and
++                    inactive is not None):
+                 break
+         else:
+             # we might get here when dealing with exotic Linux flavors, see:
+-            # http://code.google.com/p/psutil/issues/detail?id=313
++            # https://github.com/giampaolo/psutil/issues/313
+             msg = "'cached', 'active' and 'inactive' memory stats couldn't " \
+                   "be determined and were set to 0"
+             warnings.warn(msg, RuntimeWarning)
+             cached = active = inactive = 0
+-    finally:
+-        f.close()
+     avail = free + buffers + cached
+     used = total - free
+     percent = usage_percent((total - avail), total, _round=1)
+-    return nt_virtmem_info(total, avail, percent, used, free,
+-                           active, inactive, buffers, cached)
++    return svmem(total, avail, percent, used, free,
++                 active, inactive, buffers, cached)
++
+ 
+ def swap_memory():
+-    _, _, _, _, total, free = _psutil_linux.get_sysinfo()
++    _, _, _, _, total, free = cext.linux_sysinfo()
+     used = total - free
+     percent = usage_percent(used, total, _round=1)
+     # get pgin/pgouts
+-    f = open("/proc/vmstat", "r")
+-    sin = sout = None
+-    try:
++    with open("/proc/vmstat", "rb") as f:
++        sin = sout = None
+         for line in f:
+             # values are expressed in 4 kilo bytes, we want bytes instead
+-            if line.startswith('pswpin'):
+-                sin = int(line.split(' ')[1]) * 4 * 1024
+-            elif line.startswith('pswpout'):
+-                sout = int(line.split(' ')[1])  * 4 * 1024
++            if line.startswith(b'pswpin'):
++                sin = int(line.split(b' ')[1]) * 4 * 1024
++            elif line.startswith(b'pswpout'):
++                sout = int(line.split(b' ')[1]) * 4 * 1024
+             if sin is not None and sout is not None:
+                 break
+         else:
+             # we might get here when dealing with exotic Linux flavors, see:
+-            # http://code.google.com/p/psutil/issues/detail?id=313
++            # https://github.com/giampaolo/psutil/issues/313
+             msg = "'sin' and 'sout' swap memory stats couldn't " \
+                   "be determined and were set to 0"
+             warnings.warn(msg, RuntimeWarning)
+             sin = sout = 0
+-    finally:
+-        f.close()
+-    return nt_swapmeminfo(total, used, free, percent, sin, sout)
+-
+-# --- XXX deprecated memory functions
+-
+-@deprecated('psutil.virtual_memory().cached')
+-def cached_phymem():
+-    return virtual_memory().cached
+-
+-@deprecated('psutil.virtual_memory().buffers')
+-def phymem_buffers():
+-    return virtual_memory().buffers
++    return _common.sswap(total, used, free, percent, sin, sout)
+ 
+ 
+-# --- system CPU functions
+-
+-@memoize
+-def _get_cputimes_ntuple():
+-    """ Return a (nt, rindex) tuple depending on the CPU times available
+-    on this Linux kernel version which may be:
+-    user, nice, system, idle, iowait, irq, softirq [steal, [guest, [guest_nice]]]
+-    """
+-    f = open('/proc/stat', 'r')
+-    try:
+-        values = f.readline().split()[1:]
+-    finally:
+-        f.close()
+-    fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
+-    rindex = 8
+-    vlen = len(values)
+-    if vlen >= 8:
+-        # Linux >= 2.6.11
+-        fields.append('steal')
+-        rindex += 1
+-    if vlen >= 9:
+-        # Linux >= 2.6.24
+-        fields.append('guest')
+-        rindex += 1
+-    if vlen >= 10:
+-        # Linux >= 3.2.0
+-        fields.append('guest_nice')
+-        rindex += 1
+-    return (namedtuple('cputimes', ' '.join(fields)), rindex)
++# --- CPUs
+ 
+-def get_system_cpu_times():
++def cpu_times():
+     """Return a named tuple representing the following system-wide
+     CPU times:
+-    user, nice, system, idle, iowait, irq, softirq [steal, [guest, [guest_nice]]]
++    (user, nice, system, idle, iowait, irq, softirq [steal, [guest,
++     [guest_nice]]])
+     Last 3 fields may not be available on all Linux kernel versions.
+     """
+-    f = open('/proc/stat', 'r')
+-    try:
++    with open('/proc/stat', 'rb') as f:
+         values = f.readline().split()
+-    finally:
+-        f.close()
+-    nt, rindex = _get_cputimes_ntuple()
+-    fields = values[1:rindex]
+-    fields = [float(x) / _CLOCK_TICKS for x in fields]
+-    return nt(*fields)
++    fields = values[1:len(scputimes._fields) + 1]
++    fields = [float(x) / CLOCK_TICKS for x in fields]
++    return scputimes(*fields)
++
+ 
+-def get_system_per_cpu_times():
++def per_cpu_times():
+     """Return a list of namedtuple representing the CPU times
+     for every CPU available on the system.
+     """
+-    nt, rindex = _get_cputimes_ntuple()
+     cpus = []
+-    f = open('/proc/stat', 'r')
+-    try:
++    with open('/proc/stat', 'rb') as f:
+         # get rid of the first line which refers to system wide CPU stats
+         f.readline()
+         for line in f:
+-            if line.startswith('cpu'):
+-                fields = line.split()[1:rindex]
+-                fields = [float(x) / _CLOCK_TICKS for x in fields]
+-                entry = nt(*fields)
++            if line.startswith(b'cpu'):
++                values = line.split()
++                fields = values[1:len(scputimes._fields) + 1]
++                fields = [float(x) / CLOCK_TICKS for x in fields]
++                entry = scputimes(*fields)
+                 cpus.append(entry)
+         return cpus
+-    finally:
+-        f.close()
+ 
+ 
+-# --- system disk functions
+-
+-def disk_partitions(all=False):
+-    """Return mounted disk partitions as a list of nameduples"""
+-    phydevs = []
+-    f = open("/proc/filesystems", "r")
++def cpu_count_logical():
++    """Return the number of logical CPUs in the system."""
+     try:
+-        for line in f:
+-            if not line.startswith("nodev"):
+-                phydevs.append(line.strip())
+-    finally:
+-        f.close()
++        return os.sysconf("SC_NPROCESSORS_ONLN")
++    except ValueError:
++        # as a second fallback we try to parse /proc/cpuinfo
++        num = 0
++        with open('/proc/cpuinfo', 'rb') as f:
++            for line in f:
++                if line.lower().startswith(b'processor'):
++                    num += 1
+ 
+-    retlist = []
+-    partitions = _psutil_linux.get_disk_partitions()
+-    for partition in partitions:
+-        device, mountpoint, fstype, opts = partition
+-        if device == 'none':
+-            device = ''
+-        if not all:
+-            if device == '' or fstype not in phydevs:
+-                continue
+-        ntuple = nt_partition(device, mountpoint, fstype, opts)
+-        retlist.append(ntuple)
+-    return retlist
++        # unknown format (e.g. amrel/sparc architectures), see:
++        # https://github.com/giampaolo/psutil/issues/200
++        # try to parse /proc/stat as a last resort
++        if num == 0:
++            search = re.compile('cpu\d')
++            with open('/proc/stat', 'rt') as f:
++                for line in f:
++                    line = line.split(' ')[0]
++                    if search.match(line):
++                        num += 1
++
++        if num == 0:
++            # mimic os.cpu_count()
++            return None
++        return num
++
++
++def cpu_count_physical():
++    """Return the number of physical cores in the system."""
++    mapping = {}
++    current_info = {}
++    with open('/proc/cpuinfo', 'rb') as f:
++        for line in f:
++            line = line.strip().lower()
++            if not line:
++                # new section
++                if (b'physical id' in current_info and
++                        b'cpu cores' in current_info):
++                    mapping[current_info[b'physical id']] = \
++                        current_info[b'cpu cores']
++                current_info = {}
++            else:
++                # ongoing section
++                if (line.startswith(b'physical id') or
++                        line.startswith(b'cpu cores')):
++                    key, value = line.split(b'\t:', 1)
++                    current_info[key] = int(value)
+ 
+-get_disk_usage = _psposix.get_disk_usage
++    # mimic os.cpu_count()
++    return sum(mapping.values()) or None
+ 
+ 
+-# --- other sysetm functions
++# --- other system functions
+ 
+-def get_system_users():
++def users():
+     """Return currently connected users as a list of namedtuples."""
+     retlist = []
+-    rawlist = _psutil_linux.get_system_users()
++    rawlist = cext.users()
+     for item in rawlist:
+         user, tty, hostname, tstamp, user_process = item
+         # note: the underlying C function includes entries about
+@@ -311,43 +313,272 @@
+         # to use them in the future.
+         if not user_process:
+             continue
+-        if hostname == ':0.0':
++        if hostname == ':0.0' or hostname == ':0':
+             hostname = 'localhost'
+-        nt = nt_user(user, tty or None, hostname, tstamp)
++        nt = _common.suser(user, tty or None, hostname, tstamp)
+         retlist.append(nt)
+     return retlist
+ 
+-# --- process functions
+ 
+-def get_pid_list():
++def boot_time():
++    """Return the system boot time expressed in seconds since the epoch."""
++    global BOOT_TIME
++    with open('/proc/stat', 'rb') as f:
++        for line in f:
++            if line.startswith(b'btime'):
++                ret = float(line.strip().split()[1])
++                BOOT_TIME = ret
++                return ret
++        raise RuntimeError("line 'btime' not found")
++
++
++# --- processes
++
++def pids():
+     """Returns a list of PIDs currently running on the system."""
+-    pids = [int(x) for x in os.listdir('/proc') if x.isdigit()]
+-    return pids
++    return [int(x) for x in os.listdir(b'/proc') if x.isdigit()]
++
+ 
+ def pid_exists(pid):
+     """Check For the existence of a unix pid."""
+     return _psposix.pid_exists(pid)
+ 
+-def network_io_counters():
++
++# --- network
++
++class Connections:
++    """A wrapper on top of /proc/net/* files, retrieving per-process
++    and system-wide open connections (TCP, UDP, UNIX) similarly to
++    "netstat -an".
++
++    Note: in case of UNIX sockets we're only able to determine the
++    local endpoint/path, not the one it's connected to.
++    According to [1] it would be possible but not easily.
++
++    [1] http://serverfault.com/a/417946
++    """
++
++    def __init__(self):
++        tcp4 = ("tcp", socket.AF_INET, socket.SOCK_STREAM)
++        tcp6 = ("tcp6", socket.AF_INET6, socket.SOCK_STREAM)
++        udp4 = ("udp", socket.AF_INET, socket.SOCK_DGRAM)
++        udp6 = ("udp6", socket.AF_INET6, socket.SOCK_DGRAM)
++        unix = ("unix", socket.AF_UNIX, None)
++        self.tmap = {
++            "all": (tcp4, tcp6, udp4, udp6, unix),
++            "tcp": (tcp4, tcp6),
++            "tcp4": (tcp4,),
++            "tcp6": (tcp6,),
++            "udp": (udp4, udp6),
++            "udp4": (udp4,),
++            "udp6": (udp6,),
++            "unix": (unix,),
++            "inet": (tcp4, tcp6, udp4, udp6),
++            "inet4": (tcp4, udp4),
++            "inet6": (tcp6, udp6),
++        }
++
++    def get_proc_inodes(self, pid):
++        inodes = defaultdict(list)
++        for fd in os.listdir("/proc/%s/fd" % pid):
++            try:
++                inode = os.readlink("/proc/%s/fd/%s" % (pid, fd))
++            except OSError:
++                # TODO: need comment here
++                continue
++            else:
++                if inode.startswith('socket:['):
++                    # the process is using a socket
++                    inode = inode[8:][:-1]
++                    inodes[inode].append((pid, int(fd)))
++        return inodes
++
++    def get_all_inodes(self):
++        inodes = {}
++        for pid in pids():
++            try:
++                inodes.update(self.get_proc_inodes(pid))
++            except OSError as err:
++                # os.listdir() is gonna raise a lot of access denied
++                # exceptions in case of unprivileged user; that's fine
++                # as we'll just end up returning a connection with PID
++                # and fd set to None anyway.
++                # Both netstat -an and lsof does the same so it's
++                # unlikely we can do any better.
++                # ENOENT just means a PID disappeared on us.
++                if err.errno not in (
++                        errno.ENOENT, errno.ESRCH, errno.EPERM, errno.EACCES):
++                    raise
++        return inodes
++
++    def decode_address(self, addr, family):
++        """Accept an "ip:port" address as displayed in /proc/net/*
++        and convert it into a human readable form, like:
++
++        "0500000A:0016" -> ("10.0.0.5", 22)
++        "0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521)
++
++        The IP address portion is a little or big endian four-byte
++        hexadecimal number; that is, the least significant byte is listed
++        first, so we need to reverse the order of the bytes to convert it
++        to an IP address.
++        The port is represented as a two-byte hexadecimal number.
++
++        Reference:
++        http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
++        """
++        ip, port = addr.split(':')
++        port = int(port, 16)
++        # this usually refers to a local socket in listen mode with
++        # no end-points connected
++        if not port:
++            return ()
++        if PY3:
++            ip = ip.encode('ascii')
++        if family == socket.AF_INET:
++            # see: https://github.com/giampaolo/psutil/issues/201
++            if sys.byteorder == 'little':
++                ip = socket.inet_ntop(family, base64.b16decode(ip)[::-1])
++            else:
++                ip = socket.inet_ntop(family, base64.b16decode(ip))
++        else:  # IPv6
++            # old version - let's keep it, just in case...
++            # ip = ip.decode('hex')
++            # return socket.inet_ntop(socket.AF_INET6,
++            #          ''.join(ip[i:i+4][::-1] for i in xrange(0, 16, 4)))
++            ip = base64.b16decode(ip)
++            # see: https://github.com/giampaolo/psutil/issues/201
++            if sys.byteorder == 'little':
++                ip = socket.inet_ntop(
++                    socket.AF_INET6,
++                    struct.pack('>4I', *struct.unpack('<4I', ip)))
++            else:
++                ip = socket.inet_ntop(
++                    socket.AF_INET6,
++                    struct.pack('<4I', *struct.unpack('<4I', ip)))
++        return (ip, port)
++
++    def process_inet(self, file, family, type_, inodes, filter_pid=None):
++        """Parse /proc/net/tcp* and /proc/net/udp* files."""
++        if file.endswith('6') and not os.path.exists(file):
++            # IPv6 not supported
++            return
++        with open(file, 'rt') as f:
++            f.readline()  # skip the first line
++            for line in f:
++                try:
++                    _, laddr, raddr, status, _, _, _, _, _, inode = \
++                        line.split()[:10]
++                except ValueError:
++                    raise RuntimeError(
++                        "error while parsing %s; malformed line %r" % (
++                            file, line))
++                if inode in inodes:
++                    # # We assume inet sockets are unique, so we error
++                    # # out if there are multiple references to the
++                    # # same inode. We won't do this for UNIX sockets.
++                    # if len(inodes[inode]) > 1 and family != socket.AF_UNIX:
++                    #     raise ValueError("ambiguos inode with multiple "
++                    #                      "PIDs references")
++                    pid, fd = inodes[inode][0]
++                else:
++                    pid, fd = None, -1
++                if filter_pid is not None and filter_pid != pid:
++                    continue
++                else:
++                    if type_ == socket.SOCK_STREAM:
++                        status = TCP_STATUSES[status]
++                    else:
++                        status = _common.CONN_NONE
++                    laddr = self.decode_address(laddr, family)
++                    raddr = self.decode_address(raddr, family)
++                    yield (fd, family, type_, laddr, raddr, status, pid)
++
++    def process_unix(self, file, family, inodes, filter_pid=None):
++        """Parse /proc/net/unix files."""
++        with open(file, 'rt') as f:
++            f.readline()  # skip the first line
++            for line in f:
++                tokens = line.split()
++                try:
++                    _, _, _, _, type_, _, inode = tokens[0:7]
++                except ValueError:
++                    raise RuntimeError(
++                        "error while parsing %s; malformed line %r" % (
++                            file, line))
++                if inode in inodes:
++                    # With UNIX sockets we can have a single inode
++                    # referencing many file descriptors.
++                    pairs = inodes[inode]
++                else:
++                    pairs = [(None, -1)]
++                for pid, fd in pairs:
++                    if filter_pid is not None and filter_pid != pid:
++                        continue
++                    else:
++                        if len(tokens) == 8:
++                            path = tokens[-1]
++                        else:
++                            path = ""
++                        type_ = int(type_)
++                        raddr = None
++                        status = _common.CONN_NONE
++                        yield (fd, family, type_, path, raddr, status, pid)
++
++    def retrieve(self, kind, pid=None):
++        if kind not in self.tmap:
++            raise ValueError("invalid %r kind argument; choose between %s"
++                             % (kind, ', '.join([repr(x) for x in self.tmap])))
++        if pid is not None:
++            inodes = self.get_proc_inodes(pid)
++            if not inodes:
++                # no connections for this process
++                return []
++        else:
++            inodes = self.get_all_inodes()
++        ret = set()
++        for f, family, type_ in self.tmap[kind]:
++            if family in (socket.AF_INET, socket.AF_INET6):
++                ls = self.process_inet(
++                    "/proc/net/%s" % f, family, type_, inodes, filter_pid=pid)
++            else:
++                ls = self.process_unix(
++                    "/proc/net/%s" % f, family, inodes, filter_pid=pid)
++            for fd, family, type_, laddr, raddr, status, bound_pid in ls:
++                if pid:
++                    conn = _common.pconn(fd, family, type_, laddr, raddr,
++                                         status)
++                else:
++                    conn = _common.sconn(fd, family, type_, laddr, raddr,
++                                         status, bound_pid)
++                ret.add(conn)
++        return list(ret)
++
++
++_connections = Connections()
++
++
++def net_connections(kind='inet'):
++    """Return system-wide open connections."""
++    return _connections.retrieve(kind)
++
++
++def net_io_counters():
+     """Return network I/O statistics for every network interface
+     installed on the system as a dict of raw tuples.
+     """
+-    f = open("/proc/net/dev", "r")
+-    try:
++    with open("/proc/net/dev", "rt") as f:
+         lines = f.readlines()
+-    finally:
+-        f.close()
+-
+     retdict = {}
+     for line in lines[2:]:
+-        colon = line.find(':')
+-        assert colon > 0, line
++        colon = line.rfind(':')
++        assert colon > 0, repr(line)
+         name = line[:colon].strip()
+-        fields = line[colon+1:].strip().split()
++        fields = line[colon + 1:].strip().split()
+         bytes_recv = int(fields[0])
+         packets_recv = int(fields[1])
+         errin = int(fields[2])
+-        dropin = int(fields[2])
++        dropin = int(fields[3])
+         bytes_sent = int(fields[8])
+         packets_sent = int(fields[9])
+         errout = int(fields[10])
+@@ -356,6 +587,26 @@
+                          errin, errout, dropin, dropout)
+     return retdict
+ 
++
++def net_if_stats():
++    """Get NIC stats (isup, duplex, speed, mtu)."""
++    duplex_map = {cext.DUPLEX_FULL: NIC_DUPLEX_FULL,
++                  cext.DUPLEX_HALF: NIC_DUPLEX_HALF,
++                  cext.DUPLEX_UNKNOWN: NIC_DUPLEX_UNKNOWN}
++    names = net_io_counters().keys()
++    ret = {}
++    for name in names:
++        isup, duplex, speed, mtu = cext.net_if_stats(name)
++        duplex = duplex_map[duplex]
++        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
++    return ret
++
++
++net_if_addrs = cext_posix.net_if_addrs
++
++
++# --- disks
++
+ def disk_io_counters():
+     """Return disk I/O statistics for every disk installed on the
+     system as a dict of raw tuples.
+@@ -367,11 +618,8 @@
+ 
+     # determine partitions we want to look for
+     partitions = []
+-    f = open("/proc/partitions", "r")
+-    try:
++    with open("/proc/partitions", "rt") as f:
+         lines = f.readlines()[2:]
+-    finally:
+-        f.close()
+     for line in reversed(lines):
+         _, _, _, name = line.split()
+         if name[-1].isdigit():
+@@ -383,18 +631,22 @@
+                 # we're dealing with a disk entity for which no
+                 # partitions have been defined (e.g. 'sda' but
+                 # 'sda1' was not around), see:
+-                # http://code.google.com/p/psutil/issues/detail?id=338
++                # https://github.com/giampaolo/psutil/issues/338
+                 partitions.append(name)
+     #
+     retdict = {}
+-    f = open("/proc/diskstats", "r")
+-    try:
++    with open("/proc/diskstats", "rt") as f:
+         lines = f.readlines()
+-    finally:
+-        f.close()
+     for line in lines:
+-        _, _, name, reads, _, rbytes, rtime, writes, _, wbytes, wtime = \
+-            line.split()[:11]
++        # http://www.mjmwired.net/kernel/Documentation/iostats.txt
++        fields = line.split()
++        if len(fields) > 7:
++            _, _, name, reads, _, rbytes, rtime, writes, _, wbytes, wtime = \
++                fields[:11]
++        else:
++            # from kernel 2.6.0 to 2.6.25
++            _, _, name, reads, rbytes, writes, wbytes = fields
++            rtime, wtime = 0, 0
+         if name in partitions:
+             rbytes = int(rbytes) * SECTOR_SIZE
+             wbytes = int(wbytes) * SECTOR_SIZE
+@@ -406,17 +658,30 @@
+     return retdict
+ 
+ 
+-# taken from /fs/proc/array.c
+-_status_map = {"R" : STATUS_RUNNING,
+-               "S" : STATUS_SLEEPING,
+-               "D" : STATUS_DISK_SLEEP,
+-               "T" : STATUS_STOPPED,
+-               "t" : STATUS_TRACING_STOP,
+-               "Z" : STATUS_ZOMBIE,
+-               "X" : STATUS_DEAD,
+-               "x" : STATUS_DEAD,
+-               "K" : STATUS_WAKE_KILL,
+-               "W" : STATUS_WAKING}
++def disk_partitions(all=False):
++    """Return mounted disk partitions as a list of namedtuples"""
++    phydevs = []
++    with open("/proc/filesystems", "r") as f:
++        for line in f:
++            if not line.startswith("nodev"):
++                phydevs.append(line.strip())
++
++    retlist = []
++    partitions = cext.disk_partitions()
++    for partition in partitions:
++        device, mountpoint, fstype, opts = partition
++        if device == 'none':
++            device = ''
++        if not all:
++            if device == '' or fstype not in phydevs:
++                continue
++        ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
++        retlist.append(ntuple)
++    return retlist
++
++
++disk_usage = _psposix.disk_usage
++
+ 
+ # --- decorators
+ 
+@@ -424,168 +689,174 @@
+     """Decorator which translates bare OSError and IOError exceptions
+     into NoSuchProcess and AccessDenied.
+     """
+-    @wraps(fun)
++    @functools.wraps(fun)
+     def wrapper(self, *args, **kwargs):
+         try:
+             return fun(self, *args, **kwargs)
+-        except EnvironmentError:
++        except EnvironmentError as err:
++            # support for private module import
++            if NoSuchProcess is None or AccessDenied is None:
++                raise
+             # ENOENT (no such file or directory) gets raised on open().
+             # ESRCH (no such process) can get raised on read() if
+             # process is gone in meantime.
+-            err = sys.exc_info()[1]
+             if err.errno in (errno.ENOENT, errno.ESRCH):
+-                raise NoSuchProcess(self.pid, self._process_name)
++                raise NoSuchProcess(self.pid, self._name)
+             if err.errno in (errno.EPERM, errno.EACCES):
+-                raise AccessDenied(self.pid, self._process_name)
++                raise AccessDenied(self.pid, self._name)
+             raise
+     return wrapper
+ 
+ 
++def wrap_exceptions_w_zombie(fun):
++    """Same as above but also handles zombies."""
++    @functools.wraps(fun)
++    def wrapper(self, *args, **kwargs):
++        try:
++            return wrap_exceptions(fun)(self)
++        except NoSuchProcess:
++            if not pid_exists(self.pid):
++                raise
++            else:
++                raise ZombieProcess(self.pid, self._name, self._ppid)
++    return wrapper
++
++
+ class Process(object):
+     """Linux process implementation."""
+ 
+-    __slots__ = ["pid", "_process_name"]
++    __slots__ = ["pid", "_name", "_ppid"]
+ 
+     def __init__(self, pid):
+         self.pid = pid
+-        self._process_name = None
++        self._name = None
++        self._ppid = None
+ 
+     @wrap_exceptions
+-    def get_process_name(self):
+-        f = open("/proc/%s/stat" % self.pid)
+-        try:
+-            name = f.read().split(' ')[1].replace('(', '').replace(')', '')
+-        finally:
+-            f.close()
++    def name(self):
++        fname = "/proc/%s/stat" % self.pid
++        kw = dict(encoding=DEFAULT_ENCODING) if PY3 else dict()
++        with open(fname, "rt", **kw) as f:
++            data = f.read()
+         # XXX - gets changed later and probably needs refactoring
+-        return name
++        return data[data.find('(') + 1:data.rfind(')')]
+ 
+-    def get_process_exe(self):
++    def exe(self):
+         try:
+             exe = os.readlink("/proc/%s/exe" % self.pid)
+-        except (OSError, IOError):
+-            err = sys.exc_info()[1]
+-            if err.errno == errno.ENOENT:
++        except (OSError, IOError) as err:
++            if err.errno in (errno.ENOENT, errno.ESRCH):
+                 # no such file error; might be raised also if the
+                 # path actually exists for system processes with
+                 # low pids (about 0-20)
+-                if os.path.lexists("/proc/%s/exe" % self.pid):
++                if os.path.lexists("/proc/%s" % self.pid):
+                     return ""
+                 else:
+-                    # ok, it is a process which has gone away
+-                    raise NoSuchProcess(self.pid, self._process_name)
++                    if not pid_exists(self.pid):
++                        raise NoSuchProcess(self.pid, self._name)
++                    else:
++                        raise ZombieProcess(self.pid, self._name, self._ppid)
+             if err.errno in (errno.EPERM, errno.EACCES):
+-                raise AccessDenied(self.pid, self._process_name)
++                raise AccessDenied(self.pid, self._name)
+             raise
+ 
+-        # readlink() might return paths containing null bytes causing
+-        # problems when used with other fs-related functions (os.*,
+-        # open(), ...)
+-        exe = exe.replace('\x00', '')
++        # readlink() might return paths containing null bytes ('\x00').
+         # Certain names have ' (deleted)' appended. Usually this is
+         # bogus as the file actually exists. Either way that's not
+         # important as we don't want to discriminate executables which
+         # have been deleted.
+-        if exe.endswith(" (deleted)") and not os.path.exists(exe):
++        exe = exe.split('\x00')[0]
++        if exe.endswith(' (deleted)') and not os.path.exists(exe):
+             exe = exe[:-10]
+         return exe
+ 
+     @wrap_exceptions
+-    def get_process_cmdline(self):
+-        f = open("/proc/%s/cmdline" % self.pid)
+-        try:
+-            # return the args as a list
+-            return [x for x in f.read().split('\x00') if x]
+-        finally:
+-            f.close()
++    def cmdline(self):
++        fname = "/proc/%s/cmdline" % self.pid
++        kw = dict(encoding=DEFAULT_ENCODING) if PY3 else dict()
++        with open(fname, "rt", **kw) as f:
++            return [x for x in f.read()[:-1].split('\x00')]
+ 
+     @wrap_exceptions
+-    def get_process_terminal(self):
++    def terminal(self):
+         tmap = _psposix._get_terminal_map()
+-        f = open("/proc/%s/stat" % self.pid)
+-        try:
+-            tty_nr = int(f.read().split(' ')[6])
+-        finally:
+-            f.close()
++        with open("/proc/%s/stat" % self.pid, 'rb') as f:
++            tty_nr = int(f.read().split(b' ')[6])
+         try:
+             return tmap[tty_nr]
+         except KeyError:
+             return None
+ 
+-    @wrap_exceptions
+-    def get_process_io_counters(self):
+-        f = open("/proc/%s/io" % self.pid)
+-        try:
+-            for line in f:
+-                if line.startswith("rchar"):
+-                    read_count = int(line.split()[1])
+-                elif line.startswith("wchar"):
+-                    write_count = int(line.split()[1])
+-                elif line.startswith("read_bytes"):
+-                    read_bytes = int(line.split()[1])
+-                elif line.startswith("write_bytes"):
+-                    write_bytes = int(line.split()[1])
+-            return nt_io(read_count, write_count, read_bytes, write_bytes)
+-        finally:
+-            f.close()
+-
+-    if not os.path.exists('/proc/%s/io' % os.getpid()):
+-        def get_process_io_counters(self):
+-            raise NotImplementedError("couldn't find /proc/%s/io (kernel " \
++    if os.path.exists('/proc/%s/io' % os.getpid()):
++        @wrap_exceptions
++        def io_counters(self):
++            fname = "/proc/%s/io" % self.pid
++            with open(fname, 'rb') as f:
++                rcount = wcount = rbytes = wbytes = None
++                for line in f:
++                    if rcount is None and line.startswith(b"syscr"):
++                        rcount = int(line.split()[1])
++                    elif wcount is None and line.startswith(b"syscw"):
++                        wcount = int(line.split()[1])
++                    elif rbytes is None and line.startswith(b"read_bytes"):
++                        rbytes = int(line.split()[1])
++                    elif wbytes is None and line.startswith(b"write_bytes"):
++                        wbytes = int(line.split()[1])
++                for x in (rcount, wcount, rbytes, wbytes):
++                    if x is None:
++                        raise NotImplementedError(
++                            "couldn't read all necessary info from %r" % fname)
++                return _common.pio(rcount, wcount, rbytes, wbytes)
++    else:
++        def io_counters(self):
++            raise NotImplementedError("couldn't find /proc/%s/io (kernel "
+                                       "too old?)" % self.pid)
+ 
+     @wrap_exceptions
+-    def get_cpu_times(self):
+-        f = open("/proc/%s/stat" % self.pid)
+-        try:
++    def cpu_times(self):
++        with open("/proc/%s/stat" % self.pid, 'rb') as f:
+             st = f.read().strip()
+-        finally:
+-            f.close()
+         # ignore the first two values ("pid (exe)")
+-        st = st[st.find(')') + 2:]
+-        values = st.split(' ')
+-        utime = float(values[11]) / _CLOCK_TICKS
+-        stime = float(values[12]) / _CLOCK_TICKS
+-        return nt_cputimes(utime, stime)
++        st = st[st.find(b')') + 2:]
++        values = st.split(b' ')
++        utime = float(values[11]) / CLOCK_TICKS
++        stime = float(values[12]) / CLOCK_TICKS
++        return _common.pcputimes(utime, stime)
+ 
+     @wrap_exceptions
+-    def process_wait(self, timeout=None):
++    def wait(self, timeout=None):
+         try:
+             return _psposix.wait_pid(self.pid, timeout)
+-        except TimeoutExpired:
+-            raise TimeoutExpired(self.pid, self._process_name)
++        except _psposix.TimeoutExpired:
++            # support for private module import
++            if TimeoutExpired is None:
++                raise
++            raise TimeoutExpired(timeout, self.pid, self._name)
+ 
+     @wrap_exceptions
+-    def get_process_create_time(self):
+-        f = open("/proc/%s/stat" % self.pid)
+-        try:
++    def create_time(self):
++        with open("/proc/%s/stat" % self.pid, 'rb') as f:
+             st = f.read().strip()
+-        finally:
+-            f.close()
+         # ignore the first two values ("pid (exe)")
+-        st = st[st.rfind(')') + 2:]
+-        values = st.split(' ')
++        st = st[st.rfind(b')') + 2:]
++        values = st.split(b' ')
+         # According to documentation, starttime is in field 21 and the
+         # unit is jiffies (clock ticks).
+         # We first divide it for clock ticks and then add uptime returning
+         # seconds since the epoch, in UTC.
+-        starttime = (float(values[19]) / _CLOCK_TICKS) + BOOT_TIME
+-        return starttime
++        # Also use cached value if available.
++        bt = BOOT_TIME or boot_time()
++        return (float(values[19]) / CLOCK_TICKS) + bt
+ 
+     @wrap_exceptions
+-    def get_memory_info(self):
+-        f = open("/proc/%s/statm" % self.pid)
+-        try:
++    def memory_info(self):
++        with open("/proc/%s/statm" % self.pid, 'rb') as f:
+             vms, rss = f.readline().split()[:2]
+-            return nt_meminfo(int(rss) * _PAGESIZE,
+-                              int(vms) * _PAGESIZE)
+-        finally:
+-            f.close()
+-
+-    _nt_ext_mem = namedtuple('meminfo', 'rss vms shared text lib data dirty')
++            return _common.pmem(int(rss) * PAGESIZE,
++                                int(vms) * PAGESIZE)
+ 
+     @wrap_exceptions
+-    def get_ext_memory_info(self):
++    def memory_info_ex(self):
+         #  ============================================================
+         # | FIELD  | DESCRIPTION                         | AKA  | TOP  |
+         #  ============================================================
+@@ -597,91 +868,80 @@
+         # | data   | data + stack                        | drs  | DATA |
+         # | dirty  | dirty pages (unused in Linux 2.6)   | dt   |      |
+         #  ============================================================
+-        f = open("/proc/%s/statm" % self.pid)
+-        try:
++        with open("/proc/%s/statm" % self.pid, "rb") as f:
+             vms, rss, shared, text, lib, data, dirty = \
+-              [int(x) * _PAGESIZE for x in f.readline().split()[:7]]
+-        finally:
+-            f.close()
+-        return self._nt_ext_mem(rss, vms, shared, text, lib, data, dirty)
+-
+-    _mmap_base_fields = ['path', 'rss', 'size', 'pss', 'shared_clean',
+-                         'shared_dirty', 'private_clean', 'private_dirty',
+-                         'referenced', 'anonymous', 'swap',]
+-    nt_mmap_grouped = namedtuple('mmap', ' '.join(_mmap_base_fields))
+-    nt_mmap_ext = namedtuple('mmap', 'addr perms ' + ' '.join(_mmap_base_fields))
+-
+-    def get_memory_maps(self):
+-        """Return process's mapped memory regions as a list of nameduples.
+-        Fields are explained in 'man proc'; here is an updated (Apr 2012)
+-        version: http://goo.gl/fmebo
+-        """
+-        f = None
+-        try:
+-            f = open("/proc/%s/smaps" % self.pid)
+-            first_line = f.readline()
+-            current_block = [first_line]
++                [int(x) * PAGESIZE for x in f.readline().split()[:7]]
++        return pextmem(rss, vms, shared, text, lib, data, dirty)
+ 
+-            def get_blocks():
+-                data = {}
+-                for line in f:
+-                    fields = line.split(None, 5)
+-                    if len(fields) >= 5:
+-                        yield (current_block.pop(), data)
+-                        current_block.append(line)
+-                    else:
+-                        data[fields[0]] = int(fields[1]) * 1024
+-                yield (current_block.pop(), data)
+-
+-            if first_line:  # smaps file can be empty
+-                for header, data in get_blocks():
+-                    hfields = header.split(None, 5)
+-                    try:
+-                        addr, perms, offset, dev, inode, path = hfields
+-                    except ValueError:
+-                        addr, perms, offset, dev, inode, path = hfields + ['']
+-                    if not path:
+-                        path = '[anon]'
+-                    else:
+-                        path = path.strip()
+-                    yield (addr, perms, path,
+-                           data['Rss:'],
+-                           data.get('Size:', 0),
+-                           data.get('Pss:', 0),
+-                           data.get('Shared_Clean:', 0),
+-                           data.get('Shared_Dirty:', 0),
+-                           data.get('Private_Clean:', 0),
+-                           data.get('Private_Dirty:', 0),
+-                           data.get('Referenced:', 0),
+-                           data.get('Anonymous:', 0),
+-                           data.get('Swap:', 0))
+-            f.close()
+-        except EnvironmentError:
+-            # XXX - Can't use wrap_exceptions decorator as we're
+-            # returning a generator;  this probably needs some
+-            # refactoring in order to avoid this code duplication.
+-            if f is not None:
+-                f.close()
+-            err = sys.exc_info()[1]
+-            if err.errno in (errno.ENOENT, errno.ESRCH):
+-                raise NoSuchProcess(self.pid, self._process_name)
+-            if err.errno in (errno.EPERM, errno.EACCES):
+-                raise AccessDenied(self.pid, self._process_name)
+-            raise
+-        except:
+-            if f is not None:
+-                f.close()
+-            raise
+-        f.close()
++    if os.path.exists('/proc/%s/smaps' % os.getpid()):
+ 
+-    if not os.path.exists('/proc/%s/smaps' % os.getpid()):
+-        def get_shared_libs(self, ext):
+-            msg = "couldn't find /proc/%s/smaps; kernel < 2.6.14 or CONFIG_MMU " \
+-                  "kernel configuration option is not enabled" % self.pid
++        @wrap_exceptions
++        def memory_maps(self):
++            """Return process's mapped memory regions as a list of named tuples.
++            Fields are explained in 'man proc'; here is an updated (Apr 2012)
++            version: http://goo.gl/fmebo
++            """
++            with open("/proc/%s/smaps" % self.pid, "rt") as f:
++                first_line = f.readline()
++                current_block = [first_line]
++
++                def get_blocks():
++                    data = {}
++                    for line in f:
++                        fields = line.split(None, 5)
++                        if not fields[0].endswith(':'):
++                            # new block section
++                            yield (current_block.pop(), data)
++                            current_block.append(line)
++                        else:
++                            try:
++                                data[fields[0]] = int(fields[1]) * 1024
++                            except ValueError:
++                                if fields[0].startswith('VmFlags:'):
++                                    # see issue #369
++                                    continue
++                                else:
++                                    raise ValueError("don't know how to inte"
++                                                     "rpret line %r" % line)
++                    yield (current_block.pop(), data)
++
++                ls = []
++                if first_line:  # smaps file can be empty
++                    for header, data in get_blocks():
++                        hfields = header.split(None, 5)
++                        try:
++                            addr, perms, offset, dev, inode, path = hfields
++                        except ValueError:
++                            addr, perms, offset, dev, inode, path = \
++                                hfields + ['']
++                        if not path:
++                            path = '[anon]'
++                        else:
++                            path = path.strip()
++                        ls.append((
++                            addr, perms, path,
++                            data['Rss:'],
++                            data.get('Size:', 0),
++                            data.get('Pss:', 0),
++                            data.get('Shared_Clean:', 0),
++                            data.get('Shared_Dirty:', 0),
++                            data.get('Private_Clean:', 0),
++                            data.get('Private_Dirty:', 0),
++                            data.get('Referenced:', 0),
++                            data.get('Anonymous:', 0),
++                            data.get('Swap:', 0)
++                        ))
++            return ls
++
++    else:
++        def memory_maps(self):
++            msg = "couldn't find /proc/%s/smaps; kernel < 2.6.14 or "  \
++                  "CONFIG_MMU kernel configuration option is not enabled" \
++                  % self.pid
+             raise NotImplementedError(msg)
+ 
+-    @wrap_exceptions
+-    def get_process_cwd(self):
++    @wrap_exceptions_w_zombie
++    def cwd(self):
+         # readlink() might return paths containing null bytes causing
+         # problems when used with other fs-related functions (os.*,
+         # open(), ...)
+@@ -689,62 +949,53 @@
+         return path.replace('\x00', '')
+ 
+     @wrap_exceptions
+-    def get_num_ctx_switches(self):
++    def num_ctx_switches(self):
+         vol = unvol = None
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++        with open("/proc/%s/status" % self.pid, "rb") as f:
+             for line in f:
+-                if line.startswith("voluntary_ctxt_switches"):
++                if line.startswith(b"voluntary_ctxt_switches"):
+                     vol = int(line.split()[1])
+-                elif line.startswith("nonvoluntary_ctxt_switches"):
++                elif line.startswith(b"nonvoluntary_ctxt_switches"):
+                     unvol = int(line.split()[1])
+                 if vol is not None and unvol is not None:
+-                    return nt_ctxsw(vol, unvol)
+-            raise NotImplementedError("the 'voluntary_ctxt_switches' and " \
+-                "'nonvoluntary_ctxt_switches' fields were not found in " \
+-                "/proc/%s/status; the kernel is probably older than 2.6.23" \
+-                % self.pid)
+-        finally:
+-            f.close()
++                    return _common.pctxsw(vol, unvol)
++            raise NotImplementedError(
++                "'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'"
++                "fields were not found in /proc/%s/status; the kernel is "
++                "probably older than 2.6.23" % self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_num_threads(self):
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++    def num_threads(self):
++        with open("/proc/%s/status" % self.pid, "rb") as f:
+             for line in f:
+-                if line.startswith("Threads:"):
++                if line.startswith(b"Threads:"):
+                     return int(line.split()[1])
+             raise NotImplementedError("line not found")
+-        finally:
+-            f.close()
+ 
+     @wrap_exceptions
+-    def get_process_threads(self):
++    def threads(self):
+         thread_ids = os.listdir("/proc/%s/task" % self.pid)
+         thread_ids.sort()
+         retlist = []
+         hit_enoent = False
+         for thread_id in thread_ids:
++            fname = "/proc/%s/task/%s/stat" % (self.pid, thread_id)
+             try:
+-                f = open("/proc/%s/task/%s/stat" % (self.pid, thread_id))
+-            except EnvironmentError:
+-                err = sys.exc_info()[1]
++                with open(fname, 'rb') as f:
++                    st = f.read().strip()
++            except EnvironmentError as err:
+                 if err.errno == errno.ENOENT:
+                     # no such file or directory; it means thread
+                     # disappeared on us
+                     hit_enoent = True
+                     continue
+                 raise
+-            try:
+-                st = f.read().strip()
+-            finally:
+-                f.close()
+             # ignore the first two values ("pid (exe)")
+-            st = st[st.find(')') + 2:]
+-            values = st.split(' ')
+-            utime = float(values[11]) / _CLOCK_TICKS
+-            stime = float(values[12]) / _CLOCK_TICKS
+-            ntuple = nt_thread(int(thread_id), utime, stime)
++            st = st[st.find(b')') + 2:]
++            values = st.split(b' ')
++            utime = float(values[11]) / CLOCK_TICKS
++            stime = float(values[12]) / CLOCK_TICKS
++            ntuple = _common.pthread(int(thread_id), utime, stime)
+             retlist.append(ntuple)
+         if hit_enoent:
+             # raise NSP if the process disappeared on us
+@@ -752,64 +1003,51 @@
+         return retlist
+ 
+     @wrap_exceptions
+-    def get_process_nice(self):
+-        #f = open('/proc/%s/stat' % self.pid, 'r')
+-        #try:
++    def nice_get(self):
++        # with open('/proc/%s/stat' % self.pid, 'r') as f:
+         #   data = f.read()
+         #   return int(data.split()[18])
+-        #finally:
+-        #   f.close()
+ 
+         # Use C implementation
+-        return _psutil_posix.getpriority(self.pid)
++        return cext_posix.getpriority(self.pid)
+ 
+     @wrap_exceptions
+-    def set_process_nice(self, value):
+-        return _psutil_posix.setpriority(self.pid, value)
++    def nice_set(self, value):
++        return cext_posix.setpriority(self.pid, value)
+ 
+     @wrap_exceptions
+-    def get_process_cpu_affinity(self):
+-        from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
+-        bitmask = _psutil_linux.get_process_cpu_affinity(self.pid)
+-        return from_bitmask(bitmask)
++    def cpu_affinity_get(self):
++        return cext.proc_cpu_affinity_get(self.pid)
+ 
+     @wrap_exceptions
+-    def set_process_cpu_affinity(self, value):
+-        def to_bitmask(l):
+-            if not l:
+-                raise ValueError("invalid argument %r" % l)
+-            out = 0
+-            for b in l:
+-                if not isinstance(b, (int, long)) or b < 0:
+-                    raise ValueError("invalid argument %r" % b)
+-                out |= 2**b
+-            return out
+-
+-        bitmask = to_bitmask(value)
++    def cpu_affinity_set(self, cpus):
+         try:
+-            _psutil_linux.set_process_cpu_affinity(self.pid, bitmask)
+-        except OSError:
+-            err = sys.exc_info()[1]
++            cext.proc_cpu_affinity_set(self.pid, cpus)
++        except OSError as err:
+             if err.errno == errno.EINVAL:
+-                allcpus = list(range(len(get_system_per_cpu_times())))
+-                for cpu in value:
++                allcpus = tuple(range(len(per_cpu_times())))
++                for cpu in cpus:
+                     if cpu not in allcpus:
+-                        raise ValueError("invalid CPU %i" % cpu)
++                        raise ValueError("invalid CPU #%i (choose between %s)"
++                                         % (cpu, allcpus))
+             raise
+ 
+     # only starting from kernel 2.6.13
+-    if hasattr(_psutil_linux, "ioprio_get"):
++    if hasattr(cext, "proc_ioprio_get"):
+ 
+         @wrap_exceptions
+-        def get_process_ionice(self):
+-            ioclass, value = _psutil_linux.ioprio_get(self.pid)
+-            return nt_ionice(ioclass, value)
++        def ionice_get(self):
++            ioclass, value = cext.proc_ioprio_get(self.pid)
++            if enum is not None:
++                ioclass = IOPriority(ioclass)
++            return _common.pionice(ioclass, value)
+ 
+         @wrap_exceptions
+-        def set_process_ionice(self, ioclass, value):
++        def ionice_set(self, ioclass, value):
+             if ioclass in (IOPRIO_CLASS_NONE, None):
+                 if value:
+-                    raise ValueError("can't specify value with IOPRIO_CLASS_NONE")
++                    msg = "can't specify value with IOPRIO_CLASS_NONE"
++                    raise ValueError(msg)
+                 ioclass = IOPRIO_CLASS_NONE
+                 value = 0
+             if ioclass in (IOPRIO_CLASS_RT, IOPRIO_CLASS_BE):
+@@ -817,263 +1055,120 @@
+                     value = 4
+             elif ioclass == IOPRIO_CLASS_IDLE:
+                 if value:
+-                    raise ValueError("can't specify value with IOPRIO_CLASS_IDLE")
++                    msg = "can't specify value with IOPRIO_CLASS_IDLE"
++                    raise ValueError(msg)
+                 value = 0
+             else:
+                 value = 0
+             if not 0 <= value <= 8:
+-                raise ValueError("value argument range expected is between 0 and 8")
+-            return _psutil_linux.ioprio_set(self.pid, ioclass, value)
++                raise ValueError(
++                    "value argument range expected is between 0 and 8")
++            return cext.proc_ioprio_set(self.pid, ioclass, value)
++
++    if HAS_PRLIMIT:
++        @wrap_exceptions
++        def rlimit(self, resource, limits=None):
++            # if pid is 0 prlimit() applies to the calling process and
++            # we don't want that
++            if self.pid == 0:
++                raise ValueError("can't use prlimit() against PID 0 process")
++            try:
++                if limits is None:
++                    # get
++                    return cext.linux_prlimit(self.pid, resource)
++                else:
++                    # set
++                    if len(limits) != 2:
++                        raise ValueError(
++                            "second argument must be a (soft, hard) tuple")
++                    soft, hard = limits
++                    cext.linux_prlimit(self.pid, resource, soft, hard)
++            except OSError as err:
++                if err.errno == errno.ENOSYS and pid_exists(self.pid):
++                    # I saw this happening on Travis:
++                    # https://travis-ci.org/giampaolo/psutil/jobs/51368273
++                    raise ZombieProcess(self.pid, self._name, self._ppid)
++                else:
++                    raise
+ 
+     @wrap_exceptions
+-    def get_process_status(self):
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++    def status(self):
++        with open("/proc/%s/status" % self.pid, 'rb') as f:
+             for line in f:
+-                if line.startswith("State:"):
++                if line.startswith(b"State:"):
+                     letter = line.split()[1]
+-                    if letter in _status_map:
+-                        return _status_map[letter]
+-                    return constant(-1, '?')
+-        finally:
+-            f.close()
++                    if PY3:
++                        letter = letter.decode()
++                    # XXX is '?' legit? (we're not supposed to return
++                    # it anyway)
++                    return PROC_STATUSES.get(letter, '?')
+ 
+     @wrap_exceptions
+-    def get_open_files(self):
++    def open_files(self):
+         retlist = []
+         files = os.listdir("/proc/%s/fd" % self.pid)
+         hit_enoent = False
+         for fd in files:
+             file = "/proc/%s/fd/%s" % (self.pid, fd)
+-            if os.path.islink(file):
+-                try:
+-                    file = os.readlink(file)
+-                except OSError:
+-                    # ENOENT == file which is gone in the meantime
+-                    err = sys.exc_info()[1]
+-                    if err.errno == errno.ENOENT:
+-                        hit_enoent = True
+-                        continue
+-                    raise
++            try:
++                file = os.readlink(file)
++            except OSError as err:
++                # ENOENT == file which is gone in the meantime
++                if err.errno in (errno.ENOENT, errno.ESRCH):
++                    hit_enoent = True
++                    continue
++                elif err.errno == errno.EINVAL:
++                    # not a link
++                    continue
+                 else:
+-                    # If file is not an absolute path there's no way
+-                    # to tell whether it's a regular file or not,
+-                    # so we skip it. A regular file is always supposed
+-                    # to be absolutized though.
+-                    if file.startswith('/') and isfile_strict(file):
+-                        ntuple = nt_openfile(file, int(fd))
+-                        retlist.append(ntuple)
++                    raise
++            else:
++                # If file is not an absolute path there's no way
++                # to tell whether it's a regular file or not,
++                # so we skip it. A regular file is always supposed
++                # to be absolutized though.
++                if file.startswith('/') and isfile_strict(file):
++                    ntuple = _common.popenfile(file, int(fd))
++                    retlist.append(ntuple)
+         if hit_enoent:
+             # raise NSP if the process disappeared on us
+             os.stat('/proc/%s' % self.pid)
+         return retlist
+ 
+     @wrap_exceptions
+-    def get_connections(self, kind='inet'):
+-        """Return connections opened by process as a list of namedtuples.
+-        The kind parameter filters for connections that fit the following
+-        criteria:
+-
+-        Kind Value      Number of connections using
+-        inet            IPv4 and IPv6
+-        inet4           IPv4
+-        inet6           IPv6
+-        tcp             TCP
+-        tcp4            TCP over IPv4
+-        tcp6            TCP over IPv6
+-        udp             UDP
+-        udp4            UDP over IPv4
+-        udp6            UDP over IPv6
+-        all             the sum of all the possible families and protocols
+-        """
+-        # Note: in case of UNIX sockets we're only able to determine the
+-        # local bound path while the remote endpoint is not retrievable:
+-        # http://goo.gl/R3GHM
+-        inodes = {}
+-        # os.listdir() is gonna raise a lot of access denied
+-        # exceptions in case of unprivileged user; that's fine:
+-        # lsof does the same so it's unlikely that we can to better.
+-        for fd in os.listdir("/proc/%s/fd" % self.pid):
+-            try:
+-                inode = os.readlink("/proc/%s/fd/%s" % (self.pid, fd))
+-            except OSError:
+-                continue
+-            if inode.startswith('socket:['):
+-                # the process is using a socket
+-                inode = inode[8:][:-1]
+-                inodes[inode] = fd
+-
+-        if not inodes:
+-            # no connections for this process
+-            return []
+-
+-        def process(file, family, type_):
+-            retlist = []
+-            try:
+-                f = open(file, 'r')
+-            except IOError:
+-                # IPv6 not supported on this platform
+-                err = sys.exc_info()[1]
+-                if err.errno == errno.ENOENT and file.endswith('6'):
+-                    return []
+-                else:
+-                    raise
+-            try:
+-                f.readline()  # skip the first line
+-                for line in f:
+-                    # IPv4 / IPv6
+-                    if family in (socket.AF_INET, socket.AF_INET6):
+-                        _, laddr, raddr, status, _, _, _, _, _, inode = \
+-                                                                line.split()[:10]
+-                        if inode in inodes:
+-                            laddr = self._decode_address(laddr, family)
+-                            raddr = self._decode_address(raddr, family)
+-                            if type_ == socket.SOCK_STREAM:
+-                                status = _TCP_STATES_TABLE[status]
+-                            else:
+-                                status = ""
+-                            fd = int(inodes[inode])
+-                            conn = nt_connection(fd, family, type_, laddr,
+-                                                 raddr, status)
+-                            retlist.append(conn)
+-                    elif family == socket.AF_UNIX:
+-                        tokens = line.split()
+-                        _, _, _, _, type_, _, inode = tokens[0:7]
+-                        if inode in inodes:
+-
+-                            if len(tokens) == 8:
+-                                path = tokens[-1]
+-                            else:
+-                                path = ""
+-                            fd = int(inodes[inode])
+-                            type_ = int(type_)
+-                            conn = nt_connection(fd, family, type_, path,
+-                                                 None, "")
+-                            retlist.append(conn)
+-                    else:
+-                        raise ValueError(family)
+-                return retlist
+-            finally:
+-                f.close()
+-
+-        tcp4 = ("tcp" , socket.AF_INET , socket.SOCK_STREAM)
+-        tcp6 = ("tcp6", socket.AF_INET6, socket.SOCK_STREAM)
+-        udp4 = ("udp" , socket.AF_INET , socket.SOCK_DGRAM)
+-        udp6 = ("udp6", socket.AF_INET6, socket.SOCK_DGRAM)
+-        unix = ("unix", socket.AF_UNIX, None)
+-
+-        tmap = {
+-            "all"  : (tcp4, tcp6, udp4, udp6, unix),
+-            "tcp"  : (tcp4, tcp6),
+-            "tcp4" : (tcp4,),
+-            "tcp6" : (tcp6,),
+-            "udp"  : (udp4, udp6),
+-            "udp4" : (udp4,),
+-            "udp6" : (udp6,),
+-            "unix" : (unix,),
+-            "inet" : (tcp4, tcp6, udp4, udp6),
+-            "inet4": (tcp4, udp4),
+-            "inet6": (tcp6, udp6),
+-        }
+-        if kind not in tmap:
+-            raise ValueError("invalid %r kind argument; choose between %s"
+-                             % (kind, ', '.join([repr(x) for x in tmap])))
+-        ret = []
+-        for f, family, type_ in tmap[kind]:
+-            ret += process("/proc/net/%s" % f, family, type_)
++    def connections(self, kind='inet'):
++        ret = _connections.retrieve(kind, self.pid)
+         # raise NSP if the process disappeared on us
+         os.stat('/proc/%s' % self.pid)
+         return ret
+ 
+-
+-#    --- lsof implementation
+-#
+-#    def get_connections(self):
+-#        lsof = _psposix.LsofParser(self.pid, self._process_name)
+-#        return lsof.get_process_connections()
+-
+     @wrap_exceptions
+-    def get_num_fds(self):
+-       return len(os.listdir("/proc/%s/fd" % self.pid))
++    def num_fds(self):
++        return len(os.listdir("/proc/%s/fd" % self.pid))
+ 
+     @wrap_exceptions
+-    def get_process_ppid(self):
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++    def ppid(self):
++        with open("/proc/%s/status" % self.pid, 'rb') as f:
+             for line in f:
+-                if line.startswith("PPid:"):
++                if line.startswith(b"PPid:"):
+                     # PPid: nnnn
+                     return int(line.split()[1])
+             raise NotImplementedError("line not found")
+-        finally:
+-            f.close()
+ 
+     @wrap_exceptions
+-    def get_process_uids(self):
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++    def uids(self):
++        with open("/proc/%s/status" % self.pid, 'rb') as f:
+             for line in f:
+-                if line.startswith('Uid:'):
++                if line.startswith(b'Uid:'):
+                     _, real, effective, saved, fs = line.split()
+-                    return nt_uids(int(real), int(effective), int(saved))
++                    return _common.puids(int(real), int(effective), int(saved))
+             raise NotImplementedError("line not found")
+-        finally:
+-            f.close()
+ 
+     @wrap_exceptions
+-    def get_process_gids(self):
+-        f = open("/proc/%s/status" % self.pid)
+-        try:
++    def gids(self):
++        with open("/proc/%s/status" % self.pid, 'rb') as f:
+             for line in f:
+-                if line.startswith('Gid:'):
++                if line.startswith(b'Gid:'):
+                     _, real, effective, saved, fs = line.split()
+-                    return nt_gids(int(real), int(effective), int(saved))
++                    return _common.pgids(int(real), int(effective), int(saved))
+             raise NotImplementedError("line not found")
+-        finally:
+-            f.close()
+-
+-    @staticmethod
+-    def _decode_address(addr, family):
+-        """Accept an "ip:port" address as displayed in /proc/net/*
+-        and convert it into a human readable form, like:
+-
+-        "0500000A:0016" -> ("10.0.0.5", 22)
+-        "0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521)
+-
+-        The IP address portion is a little or big endian four-byte
+-        hexadecimal number; that is, the least significant byte is listed
+-        first, so we need to reverse the order of the bytes to convert it
+-        to an IP address.
+-        The port is represented as a two-byte hexadecimal number.
+-
+-        Reference:
+-        http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
+-        """
+-        ip, port = addr.split(':')
+-        port = int(port, 16)
+-        if PY3:
+-            ip = ip.encode('ascii')
+-        # this usually refers to a local socket in listen mode with
+-        # no end-points connected
+-        if not port:
+-            return ()
+-        if family == socket.AF_INET:
+-            # see: http://code.google.com/p/psutil/issues/detail?id=201
+-            if sys.byteorder == 'little':
+-                ip = socket.inet_ntop(family, base64.b16decode(ip)[::-1])
+-            else:
+-                ip = socket.inet_ntop(family, base64.b16decode(ip))
+-        else:  # IPv6
+-            # old version - let's keep it, just in case...
+-            #ip = ip.decode('hex')
+-            #return socket.inet_ntop(socket.AF_INET6,
+-            #          ''.join(ip[i:i+4][::-1] for i in xrange(0, 16, 4)))
+-            ip = base64.b16decode(ip)
+-            # see: http://code.google.com/p/psutil/issues/detail?id=201
+-            if sys.byteorder == 'little':
+-                ip = socket.inet_ntop(socket.AF_INET6,
+-                                struct.pack('>4I', *struct.unpack('<4I', ip)))
+-            else:
+-                ip = socket.inet_ntop(socket.AF_INET6,
+-                                struct.pack('<4I', *struct.unpack('<4I', ip)))
+-        return (ip, port)
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psmswindows.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psmswindows.py	1969-12-31 16:00:00.000000000 -0800
+@@ -1,455 +0,0 @@
+-#!/usr/bin/env python
+-
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+-# Use of this source code is governed by a BSD-style license that can be
+-# found in the LICENSE file.
+-
+-"""Windows platform implementation."""
+-
+-import errno
+-import os
+-import sys
+-import platform
+-import warnings
+-
+-import _psutil_mswindows
+-from _psutil_mswindows import ERROR_ACCESS_DENIED
+-from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+-from psutil._common import *
+-from psutil._compat import PY3, xrange, long, wraps
+-
+-# Windows specific extended namespace
+-__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
+-                  "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
+-                  "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS"]
+-
+-
+-# --- module level constants (gets pushed up to psutil module)
+-
+-# Since these constants get determined at import time we do not want to
+-# crash immediately; instead we'll set them to None and most likely
+-# we'll crash later as they're used for determining process CPU stats
+-# and creation_time
+-try:
+-    NUM_CPUS = _psutil_mswindows.get_num_cpus()
+-except Exception:
+-    NUM_CPUS = None
+-    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+-try:
+-    BOOT_TIME = _psutil_mswindows.get_system_boot_time()
+-except Exception:
+-    BOOT_TIME = None
+-    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+-try:
+-    TOTAL_PHYMEM = _psutil_mswindows.get_virtual_mem()[0]
+-except Exception:
+-    TOTAL_PHYMEM = None
+-    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+-
+-WAIT_TIMEOUT = 0x00000102 # 258 in decimal
+-ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED])
+-
+-# process priority constants:
+-# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
+-from _psutil_mswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
+-                               BELOW_NORMAL_PRIORITY_CLASS,
+-                               HIGH_PRIORITY_CLASS,
+-                               IDLE_PRIORITY_CLASS,
+-                               NORMAL_PRIORITY_CLASS,
+-                               REALTIME_PRIORITY_CLASS,
+-                               INFINITE)
+-
+-@memoize
+-def _win32_QueryDosDevice(s):
+-    return _psutil_mswindows.win32_QueryDosDevice(s)
+-
+-def _convert_raw_path(s):
+-    # convert paths using native DOS format like:
+-    # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
+-    # into: "C:\Windows\systemew\file.txt"
+-    if PY3 and not isinstance(s, str):
+-        s = s.decode('utf8')
+-    rawdrive = '\\'.join(s.split('\\')[:3])
+-    driveletter = _win32_QueryDosDevice(rawdrive)
+-    return os.path.join(driveletter, s[len(rawdrive):])
+-
+-
+-# --- public functions
+-
+-get_system_boot_time = _psutil_mswindows.get_system_boot_time
+-
+-nt_virtmem_info = namedtuple('vmem', ' '.join([
+-    # all platforms
+-    'total', 'available', 'percent', 'used', 'free']))
+-
+-def virtual_memory():
+-    """System virtual memory as a namedtuple."""
+-    mem = _psutil_mswindows.get_virtual_mem()
+-    totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
+-    #
+-    total = totphys
+-    avail = availphys
+-    free = availphys
+-    used = total - avail
+-    percent = usage_percent((total - avail), total, _round=1)
+-    return nt_virtmem_info(total, avail, percent, used, free)
+-
+-def swap_memory():
+-    """Swap system memory as a (total, used, free, sin, sout) tuple."""
+-    mem = _psutil_mswindows.get_virtual_mem()
+-    total = mem[2]
+-    free = mem[3]
+-    used = total - free
+-    percent = usage_percent(used, total, _round=1)
+-    return nt_swapmeminfo(total, used, free, percent, 0, 0)
+-
+-def get_disk_usage(path):
+-    """Return disk usage associated with path."""
+-    try:
+-        total, free = _psutil_mswindows.get_disk_usage(path)
+-    except WindowsError:
+-        err = sys.exc_info()[1]
+-        if not os.path.exists(path):
+-            raise OSError(errno.ENOENT, "No such file or directory: '%s'" % path)
+-        raise
+-    used = total - free
+-    percent = usage_percent(used, total, _round=1)
+-    return nt_diskinfo(total, used, free, percent)
+-
+-def disk_partitions(all):
+-    """Return disk partitions."""
+-    rawlist = _psutil_mswindows.get_disk_partitions(all)
+-    return [nt_partition(*x) for x in rawlist]
+-
+-
+-_cputimes_ntuple = namedtuple('cputimes', 'user system idle')
+-
+-def get_system_cpu_times():
+-    """Return system CPU times as a named tuple."""
+-    user, system, idle = 0, 0, 0
+-    # computes system global times summing each processor value
+-    for cpu_time in _psutil_mswindows.get_system_cpu_times():
+-        user += cpu_time[0]
+-        system += cpu_time[1]
+-        idle += cpu_time[2]
+-    return _cputimes_ntuple(user, system, idle)
+-
+-def get_system_per_cpu_times():
+-    """Return system per-CPU times as a list of named tuples."""
+-    ret = []
+-    for cpu_t in _psutil_mswindows.get_system_cpu_times():
+-        user, system, idle = cpu_t
+-        item = _cputimes_ntuple(user, system, idle)
+-        ret.append(item)
+-    return ret
+-
+-def get_system_users():
+-    """Return currently connected users as a list of namedtuples."""
+-    retlist = []
+-    rawlist = _psutil_mswindows.get_system_users()
+-    for item in rawlist:
+-        user, hostname, tstamp = item
+-        nt = nt_user(user, None, hostname, tstamp)
+-        retlist.append(nt)
+-    return retlist
+-
+-get_pid_list = _psutil_mswindows.get_pid_list
+-pid_exists = _psutil_mswindows.pid_exists
+-network_io_counters = _psutil_mswindows.get_network_io_counters
+-disk_io_counters = _psutil_mswindows.get_disk_io_counters
+-
+-# --- decorator
+-
+-def wrap_exceptions(fun):
+-    """Decorator which translates bare OSError and WindowsError
+-    exceptions into NoSuchProcess and AccessDenied.
+-    """
+-    @wraps(fun)
+-    def wrapper(self, *args, **kwargs):
+-        try:
+-            return fun(self, *args, **kwargs)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                raise AccessDenied(self.pid, self._process_name)
+-            if err.errno == errno.ESRCH:
+-                raise NoSuchProcess(self.pid, self._process_name)
+-            raise
+-    return wrapper
+-
+-
+-class Process(object):
+-    """Wrapper class around underlying C implementation."""
+-
+-    __slots__ = ["pid", "_process_name"]
+-
+-    def __init__(self, pid):
+-        self.pid = pid
+-        self._process_name = None
+-
+-    @wrap_exceptions
+-    def get_process_name(self):
+-        """Return process name as a string of limited len (15)."""
+-        return _psutil_mswindows.get_process_name(self.pid)
+-
+-    @wrap_exceptions
+-    def get_process_exe(self):
+-        # Note: os.path.exists(path) may return False even if the file
+-        # is there, see:
+-        # http://stackoverflow.com/questions/3112546/os-path-exists-lies
+-        return _convert_raw_path(_psutil_mswindows.get_process_exe(self.pid))
+-
+-    @wrap_exceptions
+-    def get_process_cmdline(self):
+-        """Return process cmdline as a list of arguments."""
+-        return _psutil_mswindows.get_process_cmdline(self.pid)
+-
+-    @wrap_exceptions
+-    def get_process_ppid(self):
+-        """Return process parent pid."""
+-        return _psutil_mswindows.get_process_ppid(self.pid)
+-
+-    def _get_raw_meminfo(self):
+-        try:
+-            return _psutil_mswindows.get_process_memory_info(self.pid)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                return _psutil_mswindows.get_process_memory_info_2(self.pid)
+-            raise
+-
+-    @wrap_exceptions
+-    def get_memory_info(self):
+-        """Returns a tuple or RSS/VMS memory usage in bytes."""
+-        # on Windows RSS == WorkingSetSize and VSM == PagefileUsage
+-        # fields of PROCESS_MEMORY_COUNTERS struct:
+-        # http://msdn.microsoft.com/en-us/library/windows/desktop/ms684877(v=vs.85).aspx
+-        t = self._get_raw_meminfo()
+-        return nt_meminfo(t[2], t[7])
+-
+-    _nt_ext_mem = namedtuple('meminfo',
+-        ' '.join(['num_page_faults',
+-                  'peak_wset',
+-                  'wset',
+-                  'peak_paged_pool',
+-                  'paged_pool',
+-                  'peak_nonpaged_pool',
+-                  'nonpaged_pool',
+-                  'pagefile',
+-                  'peak_pagefile',
+-                  'private',]))
+-
+-    @wrap_exceptions
+-    def get_ext_memory_info(self):
+-        return self._nt_ext_mem(*self._get_raw_meminfo())
+-
+-    nt_mmap_grouped = namedtuple('mmap', 'path rss')
+-    nt_mmap_ext = namedtuple('mmap', 'addr perms path rss')
+-
+-    def get_memory_maps(self):
+-        try:
+-            raw = _psutil_mswindows.get_process_memory_maps(self.pid)
+-        except OSError:
+-            # XXX - can't use wrap_exceptions decorator as we're
+-            # returning a generator; probably needs refactoring.
+-            err = sys.exc_info()[1]
+-            if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED):
+-                raise AccessDenied(self.pid, self._process_name)
+-            if err.errno == errno.ESRCH:
+-                raise NoSuchProcess(self.pid, self._process_name)
+-            raise
+-        else:
+-            for addr, perm, path, rss in raw:
+-                path = _convert_raw_path(path)
+-                addr = hex(addr)
+-                yield (addr, perm, path, rss)
+-
+-    @wrap_exceptions
+-    def kill_process(self):
+-        """Terminates the process with the given PID."""
+-        return _psutil_mswindows.kill_process(self.pid)
+-
+-    @wrap_exceptions
+-    def process_wait(self, timeout=None):
+-        if timeout is None:
+-            timeout = INFINITE
+-        else:
+-            # WaitForSingleObject() expects time in milliseconds
+-            timeout = int(timeout * 1000)
+-        ret = _psutil_mswindows.process_wait(self.pid, timeout)
+-        if ret == WAIT_TIMEOUT:
+-            raise TimeoutExpired(self.pid, self._process_name)
+-        return ret
+-
+-    @wrap_exceptions
+-    def get_process_username(self):
+-        """Return the name of the user that owns the process"""
+-        if self.pid in (0, 4):
+-            return 'NT AUTHORITY\\SYSTEM'
+-        return _psutil_mswindows.get_process_username(self.pid)
+-
+-    @wrap_exceptions
+-    def get_process_create_time(self):
+-        # special case for kernel process PIDs; return system boot time
+-        if self.pid in (0, 4):
+-            return BOOT_TIME
+-        try:
+-            return _psutil_mswindows.get_process_create_time(self.pid)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                return _psutil_mswindows.get_process_create_time_2(self.pid)
+-            raise
+-
+-    @wrap_exceptions
+-    def get_process_num_threads(self):
+-        return _psutil_mswindows.get_process_num_threads(self.pid)
+-
+-    @wrap_exceptions
+-    def get_process_threads(self):
+-        rawlist = _psutil_mswindows.get_process_threads(self.pid)
+-        retlist = []
+-        for thread_id, utime, stime in rawlist:
+-            ntuple = nt_thread(thread_id, utime, stime)
+-            retlist.append(ntuple)
+-        return retlist
+-
+-    @wrap_exceptions
+-    def get_cpu_times(self):
+-        try:
+-            ret = _psutil_mswindows.get_process_cpu_times(self.pid)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                ret = _psutil_mswindows.get_process_cpu_times_2(self.pid)
+-            else:
+-                raise
+-        return nt_cputimes(*ret)
+-
+-    @wrap_exceptions
+-    def suspend_process(self):
+-        return _psutil_mswindows.suspend_process(self.pid)
+-
+-    @wrap_exceptions
+-    def resume_process(self):
+-        return _psutil_mswindows.resume_process(self.pid)
+-
+-    @wrap_exceptions
+-    def get_process_cwd(self):
+-        if self.pid in (0, 4):
+-            raise AccessDenied(self.pid, self._process_name)
+-        # return a normalized pathname since the native C function appends
+-        # "\\" at the and of the path
+-        path = _psutil_mswindows.get_process_cwd(self.pid)
+-        return os.path.normpath(path)
+-
+-    @wrap_exceptions
+-    def get_open_files(self):
+-        if self.pid in (0, 4):
+-            return []
+-        retlist = []
+-        # Filenames come in in native format like:
+-        # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
+-        # Convert the first part in the corresponding drive letter
+-        # (e.g. "C:\") by using Windows's QueryDosDevice()
+-        raw_file_names = _psutil_mswindows.get_process_open_files(self.pid)
+-        for file in raw_file_names:
+-            file = _convert_raw_path(file)
+-            if isfile_strict(file) and file not in retlist:
+-                ntuple = nt_openfile(file, -1)
+-                retlist.append(ntuple)
+-        return retlist
+-
+-    @wrap_exceptions
+-    def get_connections(self, kind='inet'):
+-        if kind not in conn_tmap:
+-            raise ValueError("invalid %r kind argument; choose between %s"
+-                             % (kind, ', '.join([repr(x) for x in conn_tmap])))
+-        families, types = conn_tmap[kind]
+-        ret = _psutil_mswindows.get_process_connections(self.pid, families, types)
+-        return [nt_connection(*conn) for conn in ret]
+-
+-    @wrap_exceptions
+-    def get_process_nice(self):
+-        return _psutil_mswindows.get_process_priority(self.pid)
+-
+-    @wrap_exceptions
+-    def set_process_nice(self, value):
+-        return _psutil_mswindows.set_process_priority(self.pid, value)
+-
+-    # available on Windows >= Vista
+-    if hasattr(_psutil_mswindows, "get_process_io_priority"):
+-        @wrap_exceptions
+-        def get_process_ionice(self):
+-            return _psutil_mswindows.get_process_io_priority(self.pid)
+-
+-        @wrap_exceptions
+-        def set_process_ionice(self, value, _):
+-            if _:
+-                raise TypeError("set_process_ionice() on Windows takes only " \
+-                                "1 argument (2 given)")
+-            if value not in (2, 1, 0):
+-                raise ValueError("value must be 2 (normal), 1 (low) or 0 " \
+-                                 "(very low); got %r" % value)
+-            return _psutil_mswindows.set_process_io_priority(self.pid, value)
+-
+-    @wrap_exceptions
+-    def get_process_io_counters(self):
+-        try:
+-            ret = _psutil_mswindows.get_process_io_counters(self.pid)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                ret = _psutil_mswindows.get_process_io_counters_2(self.pid)
+-            else:
+-                raise
+-        return nt_io(*ret)
+-
+-    @wrap_exceptions
+-    def get_process_status(self):
+-        suspended = _psutil_mswindows.is_process_suspended(self.pid)
+-        if suspended:
+-            return STATUS_STOPPED
+-        else:
+-            return STATUS_RUNNING
+-
+-    @wrap_exceptions
+-    def get_process_cpu_affinity(self):
+-        from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
+-        bitmask = _psutil_mswindows.get_process_cpu_affinity(self.pid)
+-        return from_bitmask(bitmask)
+-
+-    @wrap_exceptions
+-    def set_process_cpu_affinity(self, value):
+-        def to_bitmask(l):
+-            if not l:
+-                raise ValueError("invalid argument %r" % l)
+-            out = 0
+-            for b in l:
+-                out |= 2**b
+-            return out
+-
+-        # SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
+-        # is returned for an invalid CPU but this seems not to be true,
+-        # therefore we check CPUs validy beforehand.
+-        allcpus = list(range(len(get_system_per_cpu_times())))
+-        for cpu in value:
+-            if cpu not in allcpus:
+-                raise ValueError("invalid CPU %r" % cpu)
+-
+-        bitmask = to_bitmask(value)
+-        _psutil_mswindows.set_process_cpu_affinity(self.pid, bitmask)
+-
+-    @wrap_exceptions
+-    def get_num_handles(self):
+-        try:
+-            return _psutil_mswindows.get_process_num_handles(self.pid)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                return _psutil_mswindows.get_process_num_handles_2(self.pid)
+-            raise
+-
+-    @wrap_exceptions
+-    def get_num_ctx_switches(self):
+-        return nt_ctxsw(*_psutil_mswindows.get_process_num_ctx_switches(self.pid))
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psosx.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psosx.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,201 +1,262 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """OSX platform implementation."""
+ 
+ import errno
++import functools
+ import os
+-import sys
+-import warnings
++from collections import namedtuple
++
++from . import _common
++from . import _psposix
++from . import _psutil_osx as cext
++from . import _psutil_posix as cext_posix
++from ._common import conn_tmap, usage_percent, isfile_strict
++from ._common import sockfam_to_enum, socktype_to_enum
+ 
+-import _psutil_osx
+-import _psutil_posix
+-from psutil import _psposix
+-from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+-from psutil._compat import namedtuple, wraps
+-from psutil._common import *
+ 
+ __extra__all__ = []
+ 
+ # --- constants
+ 
+-# Since these constants get determined at import time we do not want to
+-# crash immediately; instead we'll set them to None and most likely
+-# we'll crash later as they're used for determining process CPU stats
+-# and creation_time
+-try:
+-    NUM_CPUS = _psutil_osx.get_num_cpus()
+-except Exception:
+-    NUM_CPUS = None
+-    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+-try:
+-    BOOT_TIME = _psutil_osx.get_system_boot_time()
+-except Exception:
+-    BOOT_TIME = None
+-    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+-try:
+-    TOTAL_PHYMEM = _psutil_osx.get_virtual_mem()[0]
+-except Exception:
+-    TOTAL_PHYMEM = None
+-    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
++PAGESIZE = os.sysconf("SC_PAGE_SIZE")
++AF_LINK = cext_posix.AF_LINK
+ 
+-_PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+-_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle')
++# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
++TCP_STATUSES = {
++    cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
++    cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
++    cext.TCPS_SYN_RECEIVED: _common.CONN_SYN_RECV,
++    cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
++    cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
++    cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
++    cext.TCPS_CLOSED: _common.CONN_CLOSE,
++    cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
++    cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
++    cext.TCPS_LISTEN: _common.CONN_LISTEN,
++    cext.TCPS_CLOSING: _common.CONN_CLOSING,
++    cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
++}
+ 
+-# --- functions
++PROC_STATUSES = {
++    cext.SIDL: _common.STATUS_IDLE,
++    cext.SRUN: _common.STATUS_RUNNING,
++    cext.SSLEEP: _common.STATUS_SLEEPING,
++    cext.SSTOP: _common.STATUS_STOPPED,
++    cext.SZOMB: _common.STATUS_ZOMBIE,
++}
+ 
+-get_system_boot_time = _psutil_osx.get_system_boot_time
++scputimes = namedtuple('scputimes', ['user', 'nice', 'system', 'idle'])
+ 
+-nt_virtmem_info = namedtuple('vmem', ' '.join([
+-    # all platforms
+-    'total', 'available', 'percent', 'used', 'free',
+-    # OSX specific
+-    'active',
+-    'inactive',
+-    'wired']))
++svmem = namedtuple(
++    'svmem', ['total', 'available', 'percent', 'used', 'free',
++              'active', 'inactive', 'wired'])
++
++pextmem = namedtuple('pextmem', ['rss', 'vms', 'pfaults', 'pageins'])
++
++pmmap_grouped = namedtuple(
++    'pmmap_grouped',
++    'path rss private swapped dirtied ref_count shadow_depth')
++
++pmmap_ext = namedtuple(
++    'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
++
++# set later from __init__.py
++NoSuchProcess = None
++ZombieProcess = None
++AccessDenied = None
++TimeoutExpired = None
++
++
++# --- functions
+ 
+ def virtual_memory():
+     """System virtual memory as a namedtuple."""
+-    total, active, inactive, wired, free = _psutil_osx.get_virtual_mem()
++    total, active, inactive, wired, free = cext.virtual_mem()
+     avail = inactive + free
+     used = active + inactive + wired
+     percent = usage_percent((total - avail), total, _round=1)
+-    return nt_virtmem_info(total, avail, percent, used, free,
+-                           active, inactive, wired)
++    return svmem(total, avail, percent, used, free,
++                 active, inactive, wired)
++
+ 
+ def swap_memory():
+     """Swap system memory as a (total, used, free, sin, sout) tuple."""
+-    total, used, free, sin, sout = _psutil_osx.get_swap_mem()
++    total, used, free, sin, sout = cext.swap_mem()
+     percent = usage_percent(used, total, _round=1)
+-    return nt_swapmeminfo(total, used, free, percent, sin, sout)
++    return _common.sswap(total, used, free, percent, sin, sout)
+ 
+-def get_system_cpu_times():
++
++def cpu_times():
+     """Return system CPU times as a namedtuple."""
+-    user, nice, system, idle = _psutil_osx.get_system_cpu_times()
+-    return _cputimes_ntuple(user, nice, system, idle)
++    user, nice, system, idle = cext.cpu_times()
++    return scputimes(user, nice, system, idle)
++
+ 
+-def get_system_per_cpu_times():
++def per_cpu_times():
+     """Return system CPU times as a named tuple"""
+     ret = []
+-    for cpu_t in _psutil_osx.get_system_per_cpu_times():
++    for cpu_t in cext.per_cpu_times():
+         user, nice, system, idle = cpu_t
+-        item = _cputimes_ntuple(user, nice, system, idle)
++        item = scputimes(user, nice, system, idle)
+         ret.append(item)
+     return ret
+ 
++
++def cpu_count_logical():
++    """Return the number of logical CPUs in the system."""
++    return cext.cpu_count_logical()
++
++
++def cpu_count_physical():
++    """Return the number of physical CPUs in the system."""
++    return cext.cpu_count_phys()
++
++
++def boot_time():
++    """The system boot time expressed in seconds since the epoch."""
++    return cext.boot_time()
++
++
+ def disk_partitions(all=False):
+     retlist = []
+-    partitions = _psutil_osx.get_disk_partitions()
++    partitions = cext.disk_partitions()
+     for partition in partitions:
+         device, mountpoint, fstype, opts = partition
+         if device == 'none':
+             device = ''
+         if not all:
+-            if not os.path.isabs(device) \
+-            or not os.path.exists(device):
++            if not os.path.isabs(device) or not os.path.exists(device):
+                 continue
+-        ntuple = nt_partition(device, mountpoint, fstype, opts)
++        ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
+         retlist.append(ntuple)
+     return retlist
+ 
+-def get_system_users():
++
++def users():
+     retlist = []
+-    rawlist = _psutil_osx.get_system_users()
++    rawlist = cext.users()
+     for item in rawlist:
+         user, tty, hostname, tstamp = item
+         if tty == '~':
+             continue  # reboot or shutdown
+         if not tstamp:
+             continue
+-        nt = nt_user(user, tty or None, hostname or None, tstamp)
++        nt = _common.suser(user, tty or None, hostname or None, tstamp)
+         retlist.append(nt)
+     return retlist
+ 
+ 
+-get_pid_list = _psutil_osx.get_pid_list
++def net_connections(kind='inet'):
++    # Note: on OSX this will fail with AccessDenied unless
++    # the process is owned by root.
++    ret = []
++    for pid in pids():
++        try:
++            cons = Process(pid).connections(kind)
++        except NoSuchProcess:
++            continue
++        else:
++            if cons:
++                for c in cons:
++                    c = list(c) + [pid]
++                    ret.append(_common.sconn(*c))
++    return ret
++
++
++def net_if_stats():
++    """Get NIC stats (isup, duplex, speed, mtu)."""
++    names = net_io_counters().keys()
++    ret = {}
++    for name in names:
++        isup, duplex, speed, mtu = cext_posix.net_if_stats(name)
++        if hasattr(_common, 'NicDuplex'):
++            duplex = _common.NicDuplex(duplex)
++        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
++    return ret
++
++
++pids = cext.pids
+ pid_exists = _psposix.pid_exists
+-get_disk_usage = _psposix.get_disk_usage
+-network_io_counters = _psutil_osx.get_network_io_counters
+-disk_io_counters = _psutil_osx.get_disk_io_counters
++disk_usage = _psposix.disk_usage
++net_io_counters = cext.net_io_counters
++disk_io_counters = cext.disk_io_counters
++net_if_addrs = cext_posix.net_if_addrs
+ 
+-# --- decorator
+ 
+ def wrap_exceptions(fun):
+     """Decorator which translates bare OSError exceptions into
+     NoSuchProcess and AccessDenied.
+     """
+-    @wraps(fun)
++    @functools.wraps(fun)
+     def wrapper(self, *args, **kwargs):
+         try:
+             return fun(self, *args, **kwargs)
+-        except OSError:
+-            err = sys.exc_info()[1]
++        except OSError as err:
++            # support for private module import
++            if (NoSuchProcess is None or AccessDenied is None or
++                    ZombieProcess is None):
++                raise
+             if err.errno == errno.ESRCH:
+-                raise NoSuchProcess(self.pid, self._process_name)
++                if not pid_exists(self.pid):
++                    raise NoSuchProcess(self.pid, self._name)
++                else:
++                    raise ZombieProcess(self.pid, self._name, self._ppid)
+             if err.errno in (errno.EPERM, errno.EACCES):
+-                raise AccessDenied(self.pid, self._process_name)
++                raise AccessDenied(self.pid, self._name)
+             raise
+     return wrapper
+ 
+ 
+-_status_map = {
+-    _psutil_osx.SIDL : STATUS_IDLE,
+-    _psutil_osx.SRUN : STATUS_RUNNING,
+-    _psutil_osx.SSLEEP : STATUS_SLEEPING,
+-    _psutil_osx.SSTOP : STATUS_STOPPED,
+-    _psutil_osx.SZOMB : STATUS_ZOMBIE,
+-}
+-
+ class Process(object):
+     """Wrapper class around underlying C implementation."""
+ 
+-    __slots__ = ["pid", "_process_name"]
++    __slots__ = ["pid", "_name", "_ppid"]
+ 
+     def __init__(self, pid):
+         self.pid = pid
+-        self._process_name = None
++        self._name = None
++        self._ppid = None
+ 
+     @wrap_exceptions
+-    def get_process_name(self):
+-        """Return process name as a string of limited len (15)."""
+-        return _psutil_osx.get_process_name(self.pid)
++    def name(self):
++        return cext.proc_name(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_exe(self):
+-        return _psutil_osx.get_process_exe(self.pid)
++    def exe(self):
++        return cext.proc_exe(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_cmdline(self):
+-        """Return process cmdline as a list of arguments."""
++    def cmdline(self):
+         if not pid_exists(self.pid):
+-            raise NoSuchProcess(self.pid, self._process_name)
+-        return _psutil_osx.get_process_cmdline(self.pid)
++            raise NoSuchProcess(self.pid, self._name)
++        return cext.proc_cmdline(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_ppid(self):
+-        """Return process parent pid."""
+-        return _psutil_osx.get_process_ppid(self.pid)
++    def ppid(self):
++        return cext.proc_ppid(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_cwd(self):
+-        return _psutil_osx.get_process_cwd(self.pid)
++    def cwd(self):
++        return cext.proc_cwd(self.pid)
+ 
+     @wrap_exceptions
+-    def get_process_uids(self):
+-        real, effective, saved = _psutil_osx.get_process_uids(self.pid)
+-        return nt_uids(real, effective, saved)
++    def uids(self):
++        real, effective, saved = cext.proc_uids(self.pid)
++        return _common.puids(real, effective, saved)
+ 
+     @wrap_exceptions
+-    def get_process_gids(self):
+-        real, effective, saved = _psutil_osx.get_process_gids(self.pid)
+-        return nt_gids(real, effective, saved)
++    def gids(self):
++        real, effective, saved = cext.proc_gids(self.pid)
++        return _common.pgids(real, effective, saved)
+ 
+     @wrap_exceptions
+-    def get_process_terminal(self):
+-        tty_nr = _psutil_osx.get_process_tty_nr(self.pid)
++    def terminal(self):
++        tty_nr = cext.proc_tty_nr(self.pid)
+         tmap = _psposix._get_terminal_map()
+         try:
+             return tmap[tty_nr]
+@@ -203,109 +264,100 @@
+             return None
+ 
+     @wrap_exceptions
+-    def get_memory_info(self):
+-        """Return a tuple with the process' RSS and VMS size."""
+-        rss, vms = _psutil_osx.get_process_memory_info(self.pid)[:2]
+-        return nt_meminfo(rss, vms)
+-
+-    _nt_ext_mem = namedtuple('meminfo', 'rss vms pfaults pageins')
++    def memory_info(self):
++        rss, vms = cext.proc_memory_info(self.pid)[:2]
++        return _common.pmem(rss, vms)
+ 
+     @wrap_exceptions
+-    def get_ext_memory_info(self):
+-        """Return a tuple with the process' RSS and VMS size."""
+-        rss, vms, pfaults, pageins = _psutil_osx.get_process_memory_info(self.pid)
+-        return self._nt_ext_mem(rss, vms,
+-                                pfaults * _PAGESIZE,
+-                                pageins * _PAGESIZE)
++    def memory_info_ex(self):
++        rss, vms, pfaults, pageins = cext.proc_memory_info(self.pid)
++        return pextmem(rss, vms, pfaults * PAGESIZE, pageins * PAGESIZE)
+ 
+     @wrap_exceptions
+-    def get_cpu_times(self):
+-        user, system = _psutil_osx.get_process_cpu_times(self.pid)
+-        return nt_cputimes(user, system)
++    def cpu_times(self):
++        user, system = cext.proc_cpu_times(self.pid)
++        return _common.pcputimes(user, system)
+ 
+     @wrap_exceptions
+-    def get_process_create_time(self):
+-        """Return the start time of the process as a number of seconds since
+-        the epoch."""
+-        return _psutil_osx.get_process_create_time(self.pid)
++    def create_time(self):
++        return cext.proc_create_time(self.pid)
+ 
+     @wrap_exceptions
+-    def get_num_ctx_switches(self):
+-        return nt_ctxsw(*_psutil_osx.get_process_num_ctx_switches(self.pid))
++    def num_ctx_switches(self):
++        return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
+ 
+     @wrap_exceptions
+-    def get_process_num_threads(self):
+-        """Return the number of threads belonging to the process."""
+-        return _psutil_osx.get_process_num_threads(self.pid)
++    def num_threads(self):
++        return cext.proc_num_threads(self.pid)
+ 
+     @wrap_exceptions
+-    def get_open_files(self):
+-        """Return files opened by process."""
++    def open_files(self):
+         if self.pid == 0:
+             return []
+         files = []
+-        rawlist = _psutil_osx.get_process_open_files(self.pid)
++        rawlist = cext.proc_open_files(self.pid)
+         for path, fd in rawlist:
+             if isfile_strict(path):
+-                ntuple = nt_openfile(path, fd)
++                ntuple = _common.popenfile(path, fd)
+                 files.append(ntuple)
+         return files
+ 
+     @wrap_exceptions
+-    def get_connections(self, kind='inet'):
+-        """Return etwork connections opened by a process as a list of
+-        namedtuples.
+-        """
++    def connections(self, kind='inet'):
+         if kind not in conn_tmap:
+             raise ValueError("invalid %r kind argument; choose between %s"
+                              % (kind, ', '.join([repr(x) for x in conn_tmap])))
+         families, types = conn_tmap[kind]
+-        ret = _psutil_osx.get_process_connections(self.pid, families, types)
+-        return [nt_connection(*conn) for conn in ret]
++        rawlist = cext.proc_connections(self.pid, families, types)
++        ret = []
++        for item in rawlist:
++            fd, fam, type, laddr, raddr, status = item
++            status = TCP_STATUSES[status]
++            fam = sockfam_to_enum(fam)
++            type = socktype_to_enum(type)
++            nt = _common.pconn(fd, fam, type, laddr, raddr, status)
++            ret.append(nt)
++        return ret
+ 
+     @wrap_exceptions
+-    def get_num_fds(self):
++    def num_fds(self):
+         if self.pid == 0:
+             return 0
+-        return _psutil_osx.get_process_num_fds(self.pid)
++        return cext.proc_num_fds(self.pid)
+ 
+     @wrap_exceptions
+-    def process_wait(self, timeout=None):
++    def wait(self, timeout=None):
+         try:
+             return _psposix.wait_pid(self.pid, timeout)
+-        except TimeoutExpired:
+-            raise TimeoutExpired(self.pid, self._process_name)
++        except _psposix.TimeoutExpired:
++            # support for private module import
++            if TimeoutExpired is None:
++                raise
++            raise TimeoutExpired(timeout, self.pid, self._name)
+ 
+     @wrap_exceptions
+-    def get_process_nice(self):
+-        return _psutil_posix.getpriority(self.pid)
++    def nice_get(self):
++        return cext_posix.getpriority(self.pid)
+ 
+     @wrap_exceptions
+-    def set_process_nice(self, value):
+-        return _psutil_posix.setpriority(self.pid, value)
++    def nice_set(self, value):
++        return cext_posix.setpriority(self.pid, value)
+ 
+     @wrap_exceptions
+-    def get_process_status(self):
+-        code = _psutil_osx.get_process_status(self.pid)
+-        if code in _status_map:
+-            return _status_map[code]
+-        return constant(-1, "?")
++    def status(self):
++        code = cext.proc_status(self.pid)
++        # XXX is '?' legit? (we're not supposed to return it anyway)
++        return PROC_STATUSES.get(code, '?')
+ 
+     @wrap_exceptions
+-    def get_process_threads(self):
+-        """Return the number of threads belonging to the process."""
+-        rawlist = _psutil_osx.get_process_threads(self.pid)
++    def threads(self):
++        rawlist = cext.proc_threads(self.pid)
+         retlist = []
+         for thread_id, utime, stime in rawlist:
+-            ntuple = nt_thread(thread_id, utime, stime)
++            ntuple = _common.pthread(thread_id, utime, stime)
+             retlist.append(ntuple)
+         return retlist
+ 
+-    nt_mmap_grouped = namedtuple('mmap',
+-        'path rss private swapped dirtied ref_count shadow_depth')
+-    nt_mmap_ext = namedtuple('mmap',
+-        'addr perms path rss private swapped dirtied ref_count shadow_depth')
+-
+     @wrap_exceptions
+-    def get_memory_maps(self):
+-        return _psutil_osx.get_process_memory_maps(self.pid)
++    def memory_maps(self):
++        return cext.proc_memory_maps(self.pid)
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psposix.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psposix.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,34 +1,53 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """Routines common to all posix systems."""
+ 
+-import os
+ import errno
+-import psutil
++import glob
++import os
+ import sys
+ import time
+-import glob
+ 
+-from psutil._error import TimeoutExpired
+-from psutil._common import nt_diskinfo, usage_percent, memoize
++from ._common import sdiskusage, usage_percent, memoize
++from ._compat import PY3, unicode
++
++
++class TimeoutExpired(Exception):
++    pass
+ 
+ 
+ def pid_exists(pid):
+     """Check whether pid exists in the current process table."""
+-    if pid < 0:
+-        return False
++    if pid == 0:
++        # According to "man 2 kill" PID 0 has a special meaning:
++        # it refers to <<every process in the process group of the
++        # calling process>> so we don't want to go any further.
++        # If we get here it means this UNIX platform *does* have
++        # a process with id 0.
++        return True
+     try:
+         os.kill(pid, 0)
+-    except OSError:
+-        e = sys.exc_info()[1]
+-        return e.errno == errno.EPERM
++    except OSError as err:
++        if err.errno == errno.ESRCH:
++            # ESRCH == No such process
++            return False
++        elif err.errno == errno.EPERM:
++            # EPERM clearly means there's a process to deny access to
++            return True
++        else:
++            # According to "man 2 kill" possible error values are
++            # (EINVAL, EPERM, ESRCH) therefore we should never get
++            # here. If we do let's be explicit in considering this
++            # an error.
++            raise err
+     else:
+         return True
+ 
++
+ def wait_pid(pid, timeout=None):
+     """Wait for process with pid 'pid' to terminate and return its
+     exit status code as an integer.
+@@ -43,23 +62,24 @@
+     def check_timeout(delay):
+         if timeout is not None:
+             if timer() >= stop_at:
+-                raise TimeoutExpired(pid)
++                raise TimeoutExpired()
+         time.sleep(delay)
+         return min(delay * 2, 0.04)
+ 
+     timer = getattr(time, 'monotonic', time.time)
+     if timeout is not None:
+-        waitcall = lambda: os.waitpid(pid, os.WNOHANG)
++        def waitcall():
++            return os.waitpid(pid, os.WNOHANG)
+         stop_at = timer() + timeout
+     else:
+-        waitcall = lambda: os.waitpid(pid, 0)
++        def waitcall():
++            return os.waitpid(pid, 0)
+ 
+     delay = 0.0001
+-    while 1:
++    while True:
+         try:
+             retpid, status = waitcall()
+-        except OSError:
+-            err = sys.exc_info()[1]
++        except OSError as err:
+             if err.errno == errno.EINTR:
+                 delay = check_timeout(delay)
+                 continue
+@@ -70,7 +90,7 @@
+                 # - pid never existed in the first place
+                 # In both cases we'll eventually return None as we
+                 # can't determine its exit status code.
+-                while 1:
++                while True:
+                     if pid_exists(pid):
+                         delay = check_timeout(delay)
+                     else:
+@@ -94,9 +114,24 @@
+                 # should never happen
+                 raise RuntimeError("unknown process exit status")
+ 
+-def get_disk_usage(path):
++
++def disk_usage(path):
+     """Return disk usage associated with path."""
+-    st = os.statvfs(path)
++    try:
++        st = os.statvfs(path)
++    except UnicodeEncodeError:
++        if not PY3 and isinstance(path, unicode):
++            # this is a bug with os.statvfs() and unicode on
++            # Python 2, see:
++            # - https://github.com/giampaolo/psutil/issues/416
++            # - http://bugs.python.org/issue18695
++            try:
++                path = path.encode(sys.getfilesystemencoding())
++            except UnicodeEncodeError:
++                pass
++            st = os.statvfs(path)
++        else:
++            raise
+     free = (st.f_bavail * st.f_frsize)
+     total = (st.f_blocks * st.f_frsize)
+     used = (st.f_blocks - st.f_bfree) * st.f_frsize
+@@ -104,7 +139,8 @@
+     # NB: the percentage is -5% than what shown by df due to
+     # reserved blocks that we are currently not considering:
+     # http://goo.gl/sWGbH
+-    return nt_diskinfo(total, used, free, percent)
++    return sdiskusage(total, used, free, percent)
++
+ 
+ @memoize
+ def _get_terminal_map():
+@@ -114,8 +150,7 @@
+         assert name not in ret
+         try:
+             ret[os.stat(name).st_rdev] = name
+-        except OSError:
+-            err = sys.exc_info()[1]
++        except OSError as err:
+             if err.errno != errno.ENOENT:
+                 raise
+     return ret
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_pssunos.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_pssunos.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,553 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""Sun OS Solaris platform implementation."""
++
++import errno
++import os
++import socket
++import subprocess
++import sys
++from collections import namedtuple
++
++from . import _common
++from . import _psposix
++from . import _psutil_posix as cext_posix
++from . import _psutil_sunos as cext
++from ._common import isfile_strict, socktype_to_enum, sockfam_to_enum
++from ._common import usage_percent
++from ._compat import PY3
++
++
++__extra__all__ = ["CONN_IDLE", "CONN_BOUND"]
++
++PAGE_SIZE = os.sysconf('SC_PAGE_SIZE')
++AF_LINK = cext_posix.AF_LINK
++
++CONN_IDLE = "IDLE"
++CONN_BOUND = "BOUND"
++
++PROC_STATUSES = {
++    cext.SSLEEP: _common.STATUS_SLEEPING,
++    cext.SRUN: _common.STATUS_RUNNING,
++    cext.SZOMB: _common.STATUS_ZOMBIE,
++    cext.SSTOP: _common.STATUS_STOPPED,
++    cext.SIDL: _common.STATUS_IDLE,
++    cext.SONPROC: _common.STATUS_RUNNING,  # same as run
++    cext.SWAIT: _common.STATUS_WAITING,
++}
++
++TCP_STATUSES = {
++    cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
++    cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
++    cext.TCPS_SYN_RCVD: _common.CONN_SYN_RECV,
++    cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
++    cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
++    cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
++    cext.TCPS_CLOSED: _common.CONN_CLOSE,
++    cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
++    cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
++    cext.TCPS_LISTEN: _common.CONN_LISTEN,
++    cext.TCPS_CLOSING: _common.CONN_CLOSING,
++    cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
++    cext.TCPS_IDLE: CONN_IDLE,  # sunos specific
++    cext.TCPS_BOUND: CONN_BOUND,  # sunos specific
++}
++
++scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait'])
++svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
++pextmem = namedtuple('pextmem', ['rss', 'vms'])
++pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss', 'anon', 'locked'])
++pmmap_ext = namedtuple(
++    'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
++
++# set later from __init__.py
++NoSuchProcess = None
++ZombieProcess = None
++AccessDenied = None
++TimeoutExpired = None
++
++# --- functions
++
++disk_io_counters = cext.disk_io_counters
++net_io_counters = cext.net_io_counters
++disk_usage = _psposix.disk_usage
++net_if_addrs = cext_posix.net_if_addrs
++
++
++def virtual_memory():
++    # we could have done this with kstat, but imho this is good enough
++    total = os.sysconf('SC_PHYS_PAGES') * PAGE_SIZE
++    # note: there's no difference on Solaris
++    free = avail = os.sysconf('SC_AVPHYS_PAGES') * PAGE_SIZE
++    used = total - free
++    percent = usage_percent(used, total, _round=1)
++    return svmem(total, avail, percent, used, free)
++
++
++def swap_memory():
++    sin, sout = cext.swap_mem()
++    # XXX
++    # we are supposed to get total/free by doing so:
++    # http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/
++    #     usr/src/cmd/swap/swap.c
++    # ...nevertheless I can't manage to obtain the same numbers as 'swap'
++    # cmdline utility, so let's parse its output (sigh!)
++    p = subprocess.Popen(['/usr/bin/env', 'PATH=/usr/sbin:/sbin:%s' %
++                          os.environ['PATH'], 'swap', '-l', '-k'],
++                         stdout=subprocess.PIPE)
++    stdout, stderr = p.communicate()
++    if PY3:
++        stdout = stdout.decode(sys.stdout.encoding)
++    if p.returncode != 0:
++        raise RuntimeError("'swap -l -k' failed (retcode=%s)" % p.returncode)
++
++    lines = stdout.strip().split('\n')[1:]
++    if not lines:
++        raise RuntimeError('no swap device(s) configured')
++    total = free = 0
++    for line in lines:
++        line = line.split()
++        t, f = line[-2:]
++        t = t.replace('K', '')
++        f = f.replace('K', '')
++        total += int(int(t) * 1024)
++        free += int(int(f) * 1024)
++    used = total - free
++    percent = usage_percent(used, total, _round=1)
++    return _common.sswap(total, used, free, percent,
++                         sin * PAGE_SIZE, sout * PAGE_SIZE)
++
++
++def pids():
++    """Returns a list of PIDs currently running on the system."""
++    return [int(x) for x in os.listdir('/proc') if x.isdigit()]
++
++
++def pid_exists(pid):
++    """Check for the existence of a unix pid."""
++    return _psposix.pid_exists(pid)
++
++
++def cpu_times():
++    """Return system-wide CPU times as a named tuple"""
++    ret = cext.per_cpu_times()
++    return scputimes(*[sum(x) for x in zip(*ret)])
++
++
++def per_cpu_times():
++    """Return system per-CPU times as a list of named tuples"""
++    ret = cext.per_cpu_times()
++    return [scputimes(*x) for x in ret]
++
++
++def cpu_count_logical():
++    """Return the number of logical CPUs in the system."""
++    try:
++        return os.sysconf("SC_NPROCESSORS_ONLN")
++    except ValueError:
++        # mimic os.cpu_count() behavior
++        return None
++
++
++def cpu_count_physical():
++    """Return the number of physical CPUs in the system."""
++    return cext.cpu_count_phys()
++
++
++def boot_time():
++    """The system boot time expressed in seconds since the epoch."""
++    return cext.boot_time()
++
++
++def users():
++    """Return currently connected users as a list of namedtuples."""
++    retlist = []
++    rawlist = cext.users()
++    localhost = (':0.0', ':0')
++    for item in rawlist:
++        user, tty, hostname, tstamp, user_process = item
++        # note: the underlying C function includes entries about
++        # system boot, run level and others.  We might want
++        # to use them in the future.
++        if not user_process:
++            continue
++        if hostname in localhost:
++            hostname = 'localhost'
++        nt = _common.suser(user, tty, hostname, tstamp)
++        retlist.append(nt)
++    return retlist
++
++
++def disk_partitions(all=False):
++    """Return system disk partitions."""
++    # TODO - the filtering logic should be better checked so that
++    # it tries to reflect 'df' as much as possible
++    retlist = []
++    partitions = cext.disk_partitions()
++    for partition in partitions:
++        device, mountpoint, fstype, opts = partition
++        if device == 'none':
++            device = ''
++        if not all:
++            # Differently from, say, Linux, we don't have a list of
++            # common fs types so the best we can do, AFAIK, is to
++            # filter by filesystem having a total size > 0.
++            if not disk_usage(mountpoint).total:
++                continue
++        ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
++        retlist.append(ntuple)
++    return retlist
++
++
++def net_connections(kind, _pid=-1):
++    """Return socket connections.  If pid == -1 return system-wide
++    connections (as opposed to connections opened by one process only).
++    Only INET sockets are returned (UNIX are not).
++    """
++    cmap = _common.conn_tmap.copy()
++    if _pid == -1:
++        cmap.pop('unix', 0)
++    if kind not in cmap:
++        raise ValueError("invalid %r kind argument; choose between %s"
++                         % (kind, ', '.join([repr(x) for x in cmap])))
++    families, types = _common.conn_tmap[kind]
++    rawlist = cext.net_connections(_pid, families, types)
++    ret = set()
++    for item in rawlist:
++        fd, fam, type_, laddr, raddr, status, pid = item
++        if fam not in families:
++            continue
++        if type_ not in types:
++            continue
++        status = TCP_STATUSES[status]
++        fam = sockfam_to_enum(fam)
++        type_ = socktype_to_enum(type_)
++        if _pid == -1:
++            nt = _common.sconn(fd, fam, type_, laddr, raddr, status, pid)
++        else:
++            nt = _common.pconn(fd, fam, type_, laddr, raddr, status)
++        ret.add(nt)
++    return list(ret)
++
++
++def net_if_stats():
++    """Get NIC stats (isup, duplex, speed, mtu)."""
++    ret = cext.net_if_stats()
++    for name, items in ret.items():
++        isup, duplex, speed, mtu = items
++        if hasattr(_common, 'NicDuplex'):
++            duplex = _common.NicDuplex(duplex)
++        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
++    return ret
++
++
++def wrap_exceptions(fun):
++    """Call callable into a try/except clause and translate ENOENT,
++    EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
++    """
++    def wrapper(self, *args, **kwargs):
++        try:
++            return fun(self, *args, **kwargs)
++        except EnvironmentError as err:
++            # support for private module import
++            if (NoSuchProcess is None or AccessDenied is None or
++                    ZombieProcess is None):
++                raise
++            # ENOENT (no such file or directory) gets raised on open().
++            # ESRCH (no such process) can get raised on read() if
++            # process is gone in meantime.
++            if err.errno in (errno.ENOENT, errno.ESRCH):
++                if not pid_exists(self.pid):
++                    raise NoSuchProcess(self.pid, self._name)
++                else:
++                    raise ZombieProcess(self.pid, self._name, self._ppid)
++            if err.errno in (errno.EPERM, errno.EACCES):
++                raise AccessDenied(self.pid, self._name)
++            raise
++    return wrapper
++
++
++class Process(object):
++    """Wrapper class around underlying C implementation."""
++
++    __slots__ = ["pid", "_name", "_ppid"]
++
++    def __init__(self, pid):
++        self.pid = pid
++        self._name = None
++        self._ppid = None
++
++    @wrap_exceptions
++    def name(self):
++        # note: max len == 15
++        return cext.proc_name_and_args(self.pid)[0]
++
++    @wrap_exceptions
++    def exe(self):
++        # Will be guess later from cmdline but we want to explicitly
++        # invoke cmdline here in order to get an AccessDenied
++        # exception if the user has not enough privileges.
++        self.cmdline()
++        return ""
++
++    @wrap_exceptions
++    def cmdline(self):
++        return cext.proc_name_and_args(self.pid)[1].split(' ')
++
++    @wrap_exceptions
++    def create_time(self):
++        return cext.proc_basic_info(self.pid)[3]
++
++    @wrap_exceptions
++    def num_threads(self):
++        return cext.proc_basic_info(self.pid)[5]
++
++    @wrap_exceptions
++    def nice_get(self):
++        # For some reason getpriority(3) return ESRCH (no such process)
++        # for certain low-pid processes, no matter what (even as root).
++        # The process actually exists though, as it has a name,
++        # creation time, etc.
++        # The best thing we can do here appears to be raising AD.
++        # Note: tested on Solaris 11; on Open Solaris 5 everything is
++        # fine.
++        try:
++            return cext_posix.getpriority(self.pid)
++        except EnvironmentError as err:
++            # 48 is 'operation not supported' but errno does not expose
++            # it. It occurs for low system pids.
++            if err.errno in (errno.ENOENT, errno.ESRCH, 48):
++                if pid_exists(self.pid):
++                    raise AccessDenied(self.pid, self._name)
++            raise
++
++    @wrap_exceptions
++    def nice_set(self, value):
++        if self.pid in (2, 3):
++            # Special case PIDs: internally setpriority(3) return ESRCH
++            # (no such process), no matter what.
++            # The process actually exists though, as it has a name,
++            # creation time, etc.
++            raise AccessDenied(self.pid, self._name)
++        return cext_posix.setpriority(self.pid, value)
++
++    @wrap_exceptions
++    def ppid(self):
++        return cext.proc_basic_info(self.pid)[0]
++
++    @wrap_exceptions
++    def uids(self):
++        real, effective, saved, _, _, _ = cext.proc_cred(self.pid)
++        return _common.puids(real, effective, saved)
++
++    @wrap_exceptions
++    def gids(self):
++        _, _, _, real, effective, saved = cext.proc_cred(self.pid)
++        return _common.puids(real, effective, saved)
++
++    @wrap_exceptions
++    def cpu_times(self):
++        user, system = cext.proc_cpu_times(self.pid)
++        return _common.pcputimes(user, system)
++
++    @wrap_exceptions
++    def terminal(self):
++        hit_enoent = False
++        tty = wrap_exceptions(
++            cext.proc_basic_info(self.pid)[0])
++        if tty != cext.PRNODEV:
++            for x in (0, 1, 2, 255):
++                try:
++                    return os.readlink('/proc/%d/path/%d' % (self.pid, x))
++                except OSError as err:
++                    if err.errno == errno.ENOENT:
++                        hit_enoent = True
++                        continue
++                    raise
++        if hit_enoent:
++            # raise NSP if the process disappeared on us
++            os.stat('/proc/%s' % self.pid)
++
++    @wrap_exceptions
++    def cwd(self):
++        # /proc/PID/path/cwd may not be resolved by readlink() even if
++        # it exists (ls shows it). If that's the case and the process
++        # is still alive return None (we can return None also on BSD).
++        # Reference: http://goo.gl/55XgO
++        try:
++            return os.readlink("/proc/%s/path/cwd" % self.pid)
++        except OSError as err:
++            if err.errno == errno.ENOENT:
++                os.stat("/proc/%s" % self.pid)
++                return None
++            raise
++
++    @wrap_exceptions
++    def memory_info(self):
++        ret = cext.proc_basic_info(self.pid)
++        rss, vms = ret[1] * 1024, ret[2] * 1024
++        return _common.pmem(rss, vms)
++
++    # it seems Solaris uses rss and vms only
++    memory_info_ex = memory_info
++
++    @wrap_exceptions
++    def status(self):
++        code = cext.proc_basic_info(self.pid)[6]
++        # XXX is '?' legit? (we're not supposed to return it anyway)
++        return PROC_STATUSES.get(code, '?')
++
++    @wrap_exceptions
++    def threads(self):
++        ret = []
++        tids = os.listdir('/proc/%d/lwp' % self.pid)
++        hit_enoent = False
++        for tid in tids:
++            tid = int(tid)
++            try:
++                utime, stime = cext.query_process_thread(
++                    self.pid, tid)
++            except EnvironmentError as err:
++                # ENOENT == thread gone in meantime
++                if err.errno == errno.ENOENT:
++                    hit_enoent = True
++                    continue
++                raise
++            else:
++                nt = _common.pthread(tid, utime, stime)
++                ret.append(nt)
++        if hit_enoent:
++            # raise NSP if the process disappeared on us
++            os.stat('/proc/%s' % self.pid)
++        return ret
++
++    @wrap_exceptions
++    def open_files(self):
++        retlist = []
++        hit_enoent = False
++        pathdir = '/proc/%d/path' % self.pid
++        for fd in os.listdir('/proc/%d/fd' % self.pid):
++            path = os.path.join(pathdir, fd)
++            if os.path.islink(path):
++                try:
++                    file = os.readlink(path)
++                except OSError as err:
++                    # ENOENT == file which is gone in the meantime
++                    if err.errno == errno.ENOENT:
++                        hit_enoent = True
++                        continue
++                    raise
++                else:
++                    if isfile_strict(file):
++                        retlist.append(_common.popenfile(file, int(fd)))
++        if hit_enoent:
++            # raise NSP if the process disappeared on us
++            os.stat('/proc/%s' % self.pid)
++        return retlist
++
++    def _get_unix_sockets(self, pid):
++        """Get UNIX sockets used by process by parsing 'pfiles' output."""
++        # TODO: rewrite this in C (...but the damn netstat source code
++        # does not include this part! Argh!!)
++        cmd = "pfiles %s" % pid
++        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
++                             stderr=subprocess.PIPE)
++        stdout, stderr = p.communicate()
++        if PY3:
++            stdout, stderr = [x.decode(sys.stdout.encoding)
++                              for x in (stdout, stderr)]
++        if p.returncode != 0:
++            if 'permission denied' in stderr.lower():
++                raise AccessDenied(self.pid, self._name)
++            if 'no such process' in stderr.lower():
++                raise NoSuchProcess(self.pid, self._name)
++            raise RuntimeError("%r command error\n%s" % (cmd, stderr))
++
++        lines = stdout.split('\n')[2:]
++        for i, line in enumerate(lines):
++            line = line.lstrip()
++            if line.startswith('sockname: AF_UNIX'):
++                path = line.split(' ', 2)[2]
++                type = lines[i - 2].strip()
++                if type == 'SOCK_STREAM':
++                    type = socket.SOCK_STREAM
++                elif type == 'SOCK_DGRAM':
++                    type = socket.SOCK_DGRAM
++                else:
++                    type = -1
++                yield (-1, socket.AF_UNIX, type, path, "", _common.CONN_NONE)
++
++    @wrap_exceptions
++    def connections(self, kind='inet'):
++        ret = net_connections(kind, _pid=self.pid)
++        # The underlying C implementation retrieves all OS connections
++        # and filters them by PID.  At this point we can't tell whether
++        # an empty list means there were no connections for process or
++        # process is no longer active so we force NSP in case the PID
++        # is no longer there.
++        if not ret:
++            os.stat('/proc/%s' % self.pid)  # will raise NSP if process is gone
++
++        # UNIX sockets
++        if kind in ('all', 'unix'):
++            ret.extend([_common.pconn(*conn) for conn in
++                        self._get_unix_sockets(self.pid)])
++        return ret
++
++    nt_mmap_grouped = namedtuple('mmap', 'path rss anon locked')
++    nt_mmap_ext = namedtuple('mmap', 'addr perms path rss anon locked')
++
++    @wrap_exceptions
++    def memory_maps(self):
++        def toaddr(start, end):
++            return '%s-%s' % (hex(start)[2:].strip('L'),
++                              hex(end)[2:].strip('L'))
++
++        retlist = []
++        rawlist = cext.proc_memory_maps(self.pid)
++        hit_enoent = False
++        for item in rawlist:
++            addr, addrsize, perm, name, rss, anon, locked = item
++            addr = toaddr(addr, addrsize)
++            if not name.startswith('['):
++                try:
++                    name = os.readlink('/proc/%s/path/%s' % (self.pid, name))
++                except OSError as err:
++                    if err.errno == errno.ENOENT:
++                        # sometimes the link may not be resolved by
++                        # readlink() even if it exists (ls shows it).
++                        # If that's the case we just return the
++                        # unresolved link path.
++                        # This seems an incosistency with /proc similar
++                        # to: http://goo.gl/55XgO
++                        name = '/proc/%s/path/%s' % (self.pid, name)
++                        hit_enoent = True
++                    else:
++                        raise
++            retlist.append((addr, perm, name, rss, anon, locked))
++        if hit_enoent:
++            # raise NSP if the process disappeared on us
++            os.stat('/proc/%s' % self.pid)
++        return retlist
++
++    @wrap_exceptions
++    def num_fds(self):
++        return len(os.listdir("/proc/%s/fd" % self.pid))
++
++    @wrap_exceptions
++    def num_ctx_switches(self):
++        return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid))
++
++    @wrap_exceptions
++    def wait(self, timeout=None):
++        try:
++            return _psposix.wait_pid(self.pid, timeout)
++        except _psposix.TimeoutExpired:
++            # support for private module import
++            if TimeoutExpired is None:
++                raise
++            raise TimeoutExpired(timeout, self.pid, self._name)
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_bsd.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_bsd.c	2015-06-17 19:33:33.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+@@ -21,34 +21,39 @@
+ #include <sys/user.h>
+ #include <sys/proc.h>
+ #include <sys/file.h>
++#include <sys/cpuset.h>
+ #include <net/route.h>
+ 
+ #include <sys/socket.h>
+-#include <sys/socketvar.h>    /* for struct xsocket */
+-/* for xinpcb struct */
++#include <sys/socketvar.h>    // for struct xsocket
++#include <sys/un.h>
++#include <sys/unpcb.h>
++#include <sys/sockio.h>
++// for xinpcb struct
+ #include <netinet/in.h>
+ #include <netinet/in_systm.h>
+ #include <netinet/ip.h>
+ #include <netinet/in_pcb.h>
+-#include <netinet/tcp_var.h>   /* for struct xtcpcb */
+-#include <netinet/tcp_fsm.h>   /* for TCP connection states */
+-#include <arpa/inet.h>         /* for inet_ntop() */
++#include <netinet/tcp_var.h>   // for struct xtcpcb
++#include <netinet/tcp_fsm.h>   // for TCP connection states
++#include <arpa/inet.h>         // for inet_ntop()
+ 
+ #if __FreeBSD_version < 900000
+-    #include <utmp.h>         /* system users */
++#include <utmp.h>         // system users
+ #else
+-    #include <utmpx.h>
++#include <utmpx.h>
+ #endif
+-#include <devstat.h>      /* get io counters */
+-#include <sys/vmmeter.h>  /* needed for vmtotal struct */
+-#include <libutil.h>      /* process open files, shared libs (kinfo_getvmmap) */
++#include <devstat.h>      // get io counters
++#include <sys/vmmeter.h>  // needed for vmtotal struct
++#include <libutil.h>      // process open files, shared libs (kinfo_getvmmap)
+ #include <sys/mount.h>
+ 
+-#include <net/if.h>       /* net io counters */
++#include <net/if.h>       // net io counters
+ #include <net/if_dl.h>
+ #include <net/route.h>
++#include <net/if_media.h>
+ 
+-#include <netinet/in.h>   /* process open files/connections */
++#include <netinet/in.h>   // process open files/connections
+ #include <sys/un.h>
+ 
+ #include "_psutil_bsd.h"
+@@ -64,7 +69,7 @@
+  * Utility function which fills a kinfo_proc struct based on process pid
+  */
+ static int
+-psutil_get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
++psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
+ {
+     int mib[4];
+     size_t size;
+@@ -75,14 +80,12 @@
+ 
+     size = sizeof(struct kinfo_proc);
+ 
+-    if (sysctl((int*)mib, 4, proc, &size, NULL, 0) == -1) {
++    if (sysctl((int *)mib, 4, proc, &size, NULL, 0) == -1) {
+         PyErr_SetFromErrno(PyExc_OSError);
+         return -1;
+     }
+ 
+-    /*
+-     * sysctl stores 0 in the size if we can't find the process information.
+-     */
++    // sysctl stores 0 in the size if we can't find the process information.
+     if (size == 0) {
+         NoSuchProcess();
+         return -1;
+@@ -92,29 +95,41 @@
+ 
+ 
+ /*
++ * Set exception to AccessDenied if pid exists else NoSuchProcess.
++ */
++void
++psutil_raise_ad_or_nsp(long pid) {
++    if (psutil_pid_exists(pid) == 0)
++        NoSuchProcess();
++    else
++        AccessDenied();
++}
++
++
++/*
+  * Return a Python list of all the PIDs running on the system.
+  */
+-static PyObject*
+-get_pid_list(PyObject* self, PyObject* args)
++static PyObject *
++psutil_pids(PyObject *self, PyObject *args)
+ {
+     kinfo_proc *proclist = NULL;
+     kinfo_proc *orig_address = NULL;
+     size_t num_processes;
+     size_t idx;
+-    PyObject* retlist = PyList_New(0);
+-    PyObject* pid = NULL;
++    PyObject *retlist = PyList_New(0);
++    PyObject *pid = NULL;
+ 
+-    if (retlist == NULL) {
++    if (retlist == NULL)
+         return NULL;
+-    }
+     if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
+-        PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list.");
++        PyErr_SetString(PyExc_RuntimeError,
++                        "failed to retrieve process list.");
+         goto error;
+     }
+ 
+     if (num_processes > 0) {
+         orig_address = proclist; // save so we can free it after we're done
+-        for (idx=0; idx < num_processes; idx++) {
++        for (idx = 0; idx < num_processes; idx++) {
+             pid = Py_BuildValue("i", proclist->ki_pid);
+             if (!pid)
+                 goto error;
+@@ -131,9 +146,8 @@
+ error:
+     Py_XDECREF(pid);
+     Py_DECREF(retlist);
+-    if (orig_address != NULL) {
++    if (orig_address != NULL)
+         free(orig_address);
+-    }
+     return NULL;
+ }
+ 
+@@ -142,16 +156,16 @@
+  * Return a Python float indicating the system boot time expressed in
+  * seconds since the epoch.
+  */
+-static PyObject*
+-get_system_boot_time(PyObject* self, PyObject* args)
++static PyObject *
++psutil_boot_time(PyObject *self, PyObject *args)
+ {
+-    /* fetch sysctl "kern.boottime" */
++    // fetch sysctl "kern.boottime"
+     static int request[2] = { CTL_KERN, KERN_BOOTTIME };
+     struct timeval boottime;
+     size_t len = sizeof(boottime);
+ 
+     if (sysctl(request, 2, &boottime, &len, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         return NULL;
+     }
+     return Py_BuildValue("d", (double)boottime.tv_sec);
+@@ -161,17 +175,15 @@
+ /*
+  * Return process name from kinfo_proc as a Python string.
+  */
+-static PyObject*
+-get_process_name(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_name(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("s", kp.ki_comm);
+ }
+ 
+@@ -181,8 +193,8 @@
+  * Thanks to Robert N. M. Watson:
+  * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_bin.c?v=8-CURRENT
+  */
+-static PyObject*
+-get_process_exe(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_exe(PyObject *self, PyObject *args)
+ {
+     long pid;
+     char pathname[PATH_MAX];
+@@ -190,9 +202,8 @@
+     int mib[4];
+     size_t size;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+ 
+     mib[0] = CTL_KERN;
+     mib[1] = KERN_PROC;
+@@ -206,12 +217,10 @@
+         return NULL;
+     }
+     if (size == 0 || strlen(pathname) == 0) {
+-        if (psutil_pid_exists(pid) == 0) {
++        if (psutil_pid_exists(pid) == 0)
+             return NoSuchProcess();
+-        }
+-        else {
++        else
+             strcpy(pathname, "");
+-        }
+     }
+     return Py_BuildValue("s", pathname);
+ }
+@@ -220,24 +229,22 @@
+ /*
+  * Return process cmdline as a Python list of cmdline arguments.
+  */
+-static PyObject*
+-get_process_cmdline(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cmdline(PyObject *self, PyObject *args)
+ {
+     long pid;
+-    PyObject* arglist = NULL;
++    PyObject *arglist = NULL;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+ 
+     // get the commandline, defined in arch/bsd/process_info.c
+     arglist = psutil_get_arg_list(pid);
+ 
+-    // psutil_get_arg_list() returns NULL only if psutil_get_cmd_args failed with ESRCH
+-    // (no process with that PID)
+-    if (NULL == arglist) {
++    // psutil_get_arg_list() returns NULL only if psutil_cmd_args
++    // failed with ESRCH (no process with that PID)
++    if (NULL == arglist)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+     return Py_BuildValue("N", arglist);
+ }
+ 
+@@ -245,17 +252,15 @@
+ /*
+  * Return process parent pid from kinfo_proc as a Python integer.
+  */
+-static PyObject*
+-get_process_ppid(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_ppid(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("l", (long)kp.ki_ppid);
+ }
+ 
+@@ -263,17 +268,15 @@
+ /*
+  * Return process status as a Python integer.
+  */
+-static PyObject*
+-get_process_status(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_status(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("i", (int)kp.ki_stat);
+ }
+ 
+@@ -282,20 +285,19 @@
+  * Return process real, effective and saved user ids from kinfo_proc
+  * as a Python tuple.
+  */
+-static PyObject*
+-get_process_uids(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_uids(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("lll", (long)kp.ki_ruid,
+-                                (long)kp.ki_uid,
+-                                (long)kp.ki_svuid);
++    return Py_BuildValue("lll",
++                         (long)kp.ki_ruid,
++                         (long)kp.ki_uid,
++                         (long)kp.ki_svuid);
+ }
+ 
+ 
+@@ -303,20 +305,19 @@
+  * Return process real, effective and saved group ids from kinfo_proc
+  * as a Python tuple.
+  */
+-static PyObject*
+-get_process_gids(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_gids(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("lll", (long)kp.ki_rgid,
+-                                (long)kp.ki_groups[0],
+-                                (long)kp.ki_svuid);
++    return Py_BuildValue("lll",
++                         (long)kp.ki_rgid,
++                         (long)kp.ki_groups[0],
++                         (long)kp.ki_svuid);
+ }
+ 
+ 
+@@ -324,17 +325,15 @@
+  * Return process real, effective and saved group ids from kinfo_proc
+  * as a Python tuple.
+  */
+-static PyObject*
+-get_process_tty_nr(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_tty_nr(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("i", kp.ki_tdev);
+ }
+ 
+@@ -342,37 +341,33 @@
+ /*
+  * Return the number of context switches performed by process as a tuple.
+  */
+-static PyObject*
+-get_process_num_ctx_switches(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("(ll)", kp.ki_rusage.ru_nvcsw,
+-                                 kp.ki_rusage.ru_nivcsw);
++    return Py_BuildValue("(ll)",
++                         kp.ki_rusage.ru_nvcsw,
++                         kp.ki_rusage.ru_nivcsw);
+ }
+ 
+ 
+-
+ /*
+  * Return number of threads used by process as a Python integer.
+  */
+-static PyObject*
+-get_process_num_threads(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_threads(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("l", (long)kp.ki_numthreads);
+ }
+ 
+@@ -381,29 +376,28 @@
+  * Retrieves all threads used by process returning a list of tuples
+  * including thread id, user time and system time.
+  * Thanks to Robert N. M. Watson:
+- * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_threads.c?v=8-CURRENT
++ * http://fxr.googlebit.com/source/usr.bin/procstat/
++ *     procstat_threads.c?v=8-CURRENT
+  */
+-static PyObject*
+-get_process_threads(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_threads(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int mib[4];
+     struct kinfo_proc *kip = NULL;
+-    struct kinfo_proc *kipp;
++    struct kinfo_proc *kipp = NULL;
+     int error;
+     unsigned int i;
+     size_t size;
+-    PyObject* retList = PyList_New(0);
+-    PyObject* pyTuple = NULL;
++    PyObject *retList = PyList_New(0);
++    PyObject *pyTuple = NULL;
+ 
+     if (retList == NULL)
+         return NULL;
+     if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+ 
+-    /*
+-     * We need to re-query for thread information, so don't use *kipp.
+-     */
++    // we need to re-query for thread information, so don't use *kipp
+     mib[0] = CTL_KERN;
+     mib[1] = KERN_PROC;
+     mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
+@@ -438,10 +432,10 @@
+ 
+     for (i = 0; i < size / sizeof(*kipp); i++) {
+         kipp = &kip[i];
+-        pyTuple = Py_BuildValue("Idd", kipp->ki_tid,
+-                                       TV2DOUBLE(kipp->ki_rusage.ru_utime),
+-                                       TV2DOUBLE(kipp->ki_rusage.ru_stime)
+-                                );
++        pyTuple = Py_BuildValue("Idd",
++                                kipp->ki_tid,
++                                TV2DOUBLE(kipp->ki_rusage.ru_utime),
++                                TV2DOUBLE(kipp->ki_rusage.ru_stime));
+         if (pyTuple == NULL)
+             goto error;
+         if (PyList_Append(retList, pyTuple))
+@@ -454,9 +448,8 @@
+ error:
+     Py_XDECREF(pyTuple);
+     Py_DECREF(retList);
+-    if (kip != NULL) {
++    if (kip != NULL)
+         free(kip);
+-    }
+     return NULL;
+ }
+ 
+@@ -464,18 +457,16 @@
+ /*
+  * Return a Python tuple (user_time, kernel_time)
+  */
+-static PyObject*
+-get_process_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cpu_times(PyObject *self, PyObject *args)
+ {
+     long pid;
+     double user_t, sys_t;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     // convert from microseconds to seconds
+     user_t = TV2DOUBLE(kp.ki_rusage.ru_utime);
+     sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime);
+@@ -484,10 +475,11 @@
+ 
+ 
+ /*
+- * Return a Python integer indicating the number of CPUs on the system
++ * Return the number of logical CPUs in the system.
++ * XXX this could be shared with OSX
+  */
+-static PyObject*
+-get_num_cpus(PyObject* self, PyObject* args)
++static PyObject *
++psutil_cpu_count_logical(PyObject *self, PyObject *args)
+ {
+     int mib[2];
+     int ncpu;
+@@ -497,12 +489,44 @@
+     mib[1] = HW_NCPU;
+     len = sizeof(ncpu);
+ 
+-    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
++        Py_RETURN_NONE;  // mimic os.cpu_count()
++    else
++        return Py_BuildValue("i", ncpu);
++}
++
++
++/*
++ * Return an XML string from which we'll determine the number of
++ * physical CPU cores in the system.
++ */
++static PyObject *
++psutil_cpu_count_phys(PyObject *self, PyObject *args)
++{
++    void *topology = NULL;
++    size_t size = 0;
++    PyObject *py_str;
++
++    if (sysctlbyname("kern.sched.topology_spec", NULL, &size, NULL, 0))
++        goto error;
++
++    topology = malloc(size);
++    if (!topology) {
++        PyErr_NoMemory();
+         return NULL;
+     }
+ 
+-    return Py_BuildValue("i", ncpu);
++    if (sysctlbyname("kern.sched.topology_spec", topology, &size, NULL, 0))
++        goto error;
++
++    py_str = Py_BuildValue("s", topology);
++    free(topology);
++    return py_str;
++
++error:
++    if (topology != NULL)
++        free(topology);
++    Py_RETURN_NONE;
+ }
+ 
+ 
+@@ -510,17 +534,15 @@
+  * Return a Python float indicating the process create time expressed in
+  * seconds since the epoch.
+  */
+-static PyObject*
+-get_process_create_time(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_create_time(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("d", TV2DOUBLE(kp.ki_start));
+ }
+ 
+@@ -529,51 +551,50 @@
+  * Return a Python float indicating the process create time expressed in
+  * seconds since the epoch.
+  */
+-static PyObject*
+-get_process_io_counters(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_io_counters(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     // there's apparently no way to determine bytes count, hence return -1.
+-    return Py_BuildValue("(llll)", kp.ki_rusage.ru_inblock,
+-                                   kp.ki_rusage.ru_oublock,
+-                                   -1, -1);
++    return Py_BuildValue("(llll)",
++                         kp.ki_rusage.ru_inblock,
++                         kp.ki_rusage.ru_oublock,
++                         -1,
++                         -1);
+ }
+ 
+ 
+ /*
+  * Return extended memory info for a process as a Python tuple.
+  */
+-static PyObject*
+-get_process_memory_info(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_memory_info(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("(lllll)", ptoa(kp.ki_rssize),    // rss
+-                                    (long)kp.ki_size,      // vms
+-                                    ptoa(kp.ki_tsize),     // text
+-                                    ptoa(kp.ki_dsize),     // data
+-                                    ptoa(kp.ki_ssize));    // stack
++    return Py_BuildValue("(lllll)",
++                         ptoa(kp.ki_rssize),    // rss
++                         (long)kp.ki_size,      // vms
++                         ptoa(kp.ki_tsize),     // text
++                         ptoa(kp.ki_dsize),     // data
++                         ptoa(kp.ki_ssize));    // stack
+ }
+ 
+ 
+ /*
+  * Return virtual memory usage statistics.
+  */
+-static PyObject*
+-get_virtual_mem(PyObject* self, PyObject* args)
++static PyObject *
++psutil_virtual_mem(PyObject *self, PyObject *args)
+ {
+     unsigned int   total, active, inactive, wired, cached, free;
+     size_t         size = sizeof(total);
+@@ -591,7 +612,8 @@
+         goto error;
+     if (sysctlbyname("vm.stats.vm.v_active_count", &active, &size, NULL, 0))
+         goto error;
+-    if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive, &size, NULL, 0))
++    if (sysctlbyname("vm.stats.vm.v_inactive_count",
++                     &inactive, &size, NULL, 0))
+         goto error;
+     if (sysctlbyname("vm.stats.vm.v_wire_count", &wired, &size, NULL, 0))
+         goto error;
+@@ -618,7 +640,7 @@
+     );
+ 
+ error:
+-    PyErr_SetFromErrno(0);
++    PyErr_SetFromErrno(PyExc_OSError);
+     return NULL;
+ }
+ 
+@@ -630,8 +652,8 @@
+ /*
+  * Return swap memory stats (see 'swapinfo' cmdline tool)
+  */
+-static PyObject*
+-get_swap_mem(PyObject* self, PyObject* args)
++static PyObject *
++psutil_swap_mem(PyObject *self, PyObject *args)
+ {
+     kvm_t *kd;
+     struct kvm_swap kvmsw[1];
+@@ -662,14 +684,14 @@
+         goto sbn_error;
+ 
+     return Py_BuildValue("(iiiII)",
+-                            kvmsw[0].ksw_total,                     // total
+-                            kvmsw[0].ksw_used,                      // used
+-                            kvmsw[0].ksw_total - kvmsw[0].ksw_used, // free
+-                            swapin + swapout,                       // swap in
+-                            nodein + nodeout);                      // swap out
++                         kvmsw[0].ksw_total,                     // total
++                         kvmsw[0].ksw_used,                      // used
++                         kvmsw[0].ksw_total - kvmsw[0].ksw_used, // free
++                         swapin + swapout,                       // swap in
++                         nodein + nodeout);                      // swap out
+ 
+ sbn_error:
+-    PyErr_SetFromErrno(0);
++    PyErr_SetFromErrno(PyExc_OSError);
+     return NULL;
+ }
+ 
+@@ -677,8 +699,8 @@
+ /*
+  * Return a Python tuple representing user, kernel and idle CPU times
+  */
+-static PyObject*
+-get_system_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_cpu_times(PyObject *self, PyObject *args)
+ {
+     long cpu_time[CPUSTATES];
+     size_t size;
+@@ -686,7 +708,7 @@
+     size = sizeof(cpu_time);
+ 
+     if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         return NULL;
+     }
+ 
+@@ -696,9 +718,10 @@
+                          (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC,
+                          (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC,
+                          (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC
+-    );
++                        );
+ }
+ 
++
+ /*
+  * XXX
+  * These functions are available on FreeBSD 8 only.
+@@ -709,10 +732,13 @@
+ 
+ #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+ /*
+- * Return files opened by process as a list of (path, fd) tuples
++ * Return files opened by process as a list of (path, fd) tuples.
++ * TODO: this is broken as it may report empty paths. 'procstat'
++ * utility has the same problem see:
++ * https://github.com/giampaolo/psutil/issues/595
+  */
+-static PyObject*
+-get_process_open_files(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_open_files(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int i, cnt;
+@@ -726,7 +752,7 @@
+         return NULL;
+     if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
++    if (psutil_kinfo_proc(pid, &kipp) == -1)
+         goto error;
+ 
+     freep = kinfo_getfile(pid, &cnt);
+@@ -738,7 +764,7 @@
+     for (i = 0; i < cnt; i++) {
+         kif = &freep[i];
+         if ((kif->kf_type == KF_TYPE_VNODE) &&
+-            (kif->kf_vnode_type == KF_VTYPE_VREG))
++                (kif->kf_vnode_type == KF_VTYPE_VREG))
+         {
+             tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd);
+             if (tuple == NULL)
+@@ -763,8 +789,8 @@
+ /*
+  * Return files opened by process as a list of (path, fd) tuples
+  */
+-static PyObject*
+-get_process_num_fds(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_fds(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int cnt;
+@@ -774,7 +800,7 @@
+ 
+     if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
++    if (psutil_kinfo_proc(pid, &kipp) == -1)
+         return NULL;
+ 
+     freep = kinfo_getfile(pid, &cnt);
+@@ -791,8 +817,8 @@
+ /*
+  * Return process current working directory.
+  */
+-static PyObject*
+-get_process_cwd(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cwd(PyObject *self, PyObject *args)
+ {
+     long pid;
+     PyObject *path = NULL;
+@@ -804,7 +830,7 @@
+ 
+     if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
++    if (psutil_kinfo_proc(pid, &kipp) == -1)
+         goto error;
+ 
+     freep = kinfo_getfile(pid, &cnt);
+@@ -827,9 +853,8 @@
+      * (lsof can't do that it either).  Since this happens even
+      * as root we return an empty string instead of AccessDenied.
+      */
+-    if (path == NULL) {
++    if (path == NULL)
+         path = Py_BuildValue("s", "");
+-    }
+     free(freep);
+     return path;
+ 
+@@ -841,51 +866,16 @@
+ }
+ 
+ 
+-/*
+- * mathes Linux net/tcp_states.h:
+- * http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
+- */
+-static char *
+-get_connection_status(int st) {
+-    switch (st) {
+-        case TCPS_CLOSED:
+-            return "CLOSE";
+-        case TCPS_CLOSING:
+-            return "CLOSING";
+-        case TCPS_CLOSE_WAIT:
+-            return "CLOSE_WAIT";
+-        case TCPS_LISTEN:
+-            return "LISTEN";
+-        case TCPS_ESTABLISHED:
+-            return "ESTABLISHED";
+-        case TCPS_SYN_SENT:
+-            return "SYN_SENT";
+-        case TCPS_SYN_RECEIVED:
+-            return "SYN_RECV";
+-        case TCPS_FIN_WAIT_1:
+-            return "FIN_WAIT_1";
+-        case TCPS_FIN_WAIT_2:
+-            return "FIN_WAIT_2";
+-        case TCPS_LAST_ACK:
+-            return "LAST_ACK";
+-        case TCPS_TIME_WAIT:
+-            return "TIME_WAIT";
+-        default:
+-            return "?";
+-    }
+-}
+-
+-/* The tcplist fetching and walking is borrowed from netstat/inet.c. */
++// The tcplist fetching and walking is borrowed from netstat/inet.c.
+ static char *
+ psutil_fetch_tcplist(void)
+ {
+     char *buf;
+     size_t len;
+-    int error;
+ 
+     for (;;) {
+         if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) < 0) {
+-            PyErr_SetFromErrno(0);
++            PyErr_SetFromErrno(PyExc_OSError);
+             return NULL;
+         }
+         buf = malloc(len);
+@@ -895,7 +885,7 @@
+         }
+         if (sysctlbyname("net.inet.tcp.pcblist", buf, &len, NULL, 0) < 0) {
+             free(buf);
+-            PyErr_SetFromErrno(0);
++            PyErr_SetFromErrno(PyExc_OSError);
+             return NULL;
+         }
+         return buf;
+@@ -911,7 +901,8 @@
+     if (family == AF_INET) {
+         sin = (struct sockaddr_in *)ss;
+         return (sin->sin_port);
+-    } else {
++    }
++    else {
+         sin6 = (struct sockaddr_in6 *)ss;
+         return (sin6->sin6_port);
+     }
+@@ -926,7 +917,8 @@
+     if (family == AF_INET) {
+         sin = (struct sockaddr_in *)ss;
+         return (&sin->sin_addr);
+-    } else {
++    }
++    else {
+         sin6 = (struct sockaddr_in6 *)ss;
+         return (&sin6->sin6_addr);
+     }
+@@ -948,7 +940,7 @@
+     if (psutil_sockaddr_port(family, ss) != port)
+         return (0);
+     return (memcmp(psutil_sockaddr_addr(family, ss), pcb_addr,
+-        psutil_sockaddr_addrlen(family)) == 0);
++                   psutil_sockaddr_addrlen(family)) == 0);
+ }
+ 
+ static struct tcpcb *
+@@ -961,30 +953,34 @@
+ 
+     oxig = xig = (struct xinpgen *)buf;
+     for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+-         xig->xig_len > sizeof(struct xinpgen);
+-         xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
++            xig->xig_len > sizeof(struct xinpgen);
++            xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
+         tp = &((struct xtcpcb *)xig)->xt_tp;
+         inp = &((struct xtcpcb *)xig)->xt_inp;
+         so = &((struct xtcpcb *)xig)->xt_socket;
+ 
+         if (so->so_type != kif->kf_sock_type ||
+-            so->xso_family != kif->kf_sock_domain ||
+-            so->xso_protocol != kif->kf_sock_protocol)
+-                continue;
++                so->xso_family != kif->kf_sock_domain ||
++                so->xso_protocol != kif->kf_sock_protocol)
++            continue;
+ 
+         if (kif->kf_sock_domain == AF_INET) {
+-            if (!psutil_sockaddr_matches(AF_INET, inp->inp_lport, &inp->inp_laddr,
+-                &kif->kf_sa_local))
++            if (!psutil_sockaddr_matches(
++                    AF_INET, inp->inp_lport, &inp->inp_laddr,
++                    &kif->kf_sa_local))
+                 continue;
+-            if (!psutil_sockaddr_matches(AF_INET, inp->inp_fport, &inp->inp_faddr,
+-                &kif->kf_sa_peer))
++            if (!psutil_sockaddr_matches(
++                    AF_INET, inp->inp_fport, &inp->inp_faddr,
++                    &kif->kf_sa_peer))
+                 continue;
+         } else {
+-            if (!psutil_sockaddr_matches(AF_INET6, inp->inp_lport, &inp->in6p_laddr,
+-                &kif->kf_sa_local))
++            if (!psutil_sockaddr_matches(
++                    AF_INET6, inp->inp_lport, &inp->in6p_laddr,
++                    &kif->kf_sa_local))
+                 continue;
+-            if (!psutil_sockaddr_matches(AF_INET6, inp->inp_fport, &inp->in6p_faddr,
+-                &kif->kf_sa_peer))
++            if (!psutil_sockaddr_matches(
++                    AF_INET6, inp->inp_fport, &inp->in6p_faddr,
++                    &kif->kf_sa_peer))
+                 continue;
+         }
+ 
+@@ -993,18 +989,21 @@
+     return NULL;
+ }
+ 
++
++// a signaler for connections without an actual status
++static int PSUTIL_CONN_NONE = 128;
++
+ /*
+  * Return connections opened by process.
+  */
+-static PyObject*
+-get_process_connections(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_connections(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int i, cnt;
+ 
+     struct kinfo_file *freep = NULL;
+     struct kinfo_file *kif;
+-    struct kinfo_proc kipp;
+     char *tcplist = NULL;
+     struct tcpcb *tcp;
+ 
+@@ -1014,24 +1013,18 @@
+     PyObject *raddr = NULL;
+     PyObject *af_filter = NULL;
+     PyObject *type_filter = NULL;
+-    PyObject* _family = NULL;
+-    PyObject* _type = NULL;
++    PyObject *_family = NULL;
++    PyObject *_type = NULL;
+ 
+-    if (retList == NULL) {
++    if (retList == NULL)
+         return NULL;
+-    }
+-    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
++    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
+         goto error;
+-    }
+     if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
+         PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
+         goto error;
+     }
+ 
+-    if (psutil_get_kinfo_proc(pid, &kipp) == -1) {
+-        goto error;
+-    }
+-
+     freep = kinfo_getfile(pid, &cnt);
+     if (freep == NULL) {
+         psutil_raise_ad_or_nsp(pid);
+@@ -1040,55 +1033,56 @@
+ 
+     tcplist = psutil_fetch_tcplist();
+     if (tcplist == NULL) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+     for (i = 0; i < cnt; i++) {
+-        int lport, rport;
++        int lport, rport, state;
+         char lip[200], rip[200];
+         char path[PATH_MAX];
+-        char *state;
+         int inseq;
+         tuple = NULL;
+         laddr = NULL;
+         raddr = NULL;
+ 
+         kif = &freep[i];
+-        if (kif->kf_type == KF_TYPE_SOCKET)
+-        {
++        if (kif->kf_type == KF_TYPE_SOCKET) {
+             // apply filters
+             _family = PyLong_FromLong((long)kif->kf_sock_domain);
+             inseq = PySequence_Contains(af_filter, _family);
+             Py_DECREF(_family);
+-            if (inseq == 0) {
++            if (inseq == 0)
+                 continue;
+-            }
+             _type = PyLong_FromLong((long)kif->kf_sock_type);
+             inseq = PySequence_Contains(type_filter, _type);
+             Py_DECREF(_type);
+-            if (inseq == 0) {
++            if (inseq == 0)
+                 continue;
+-            }
+-
+             // IPv4 / IPv6 socket
+             if ((kif->kf_sock_domain == AF_INET) ||
+-                (kif->kf_sock_domain == AF_INET6)) {
++                    (kif->kf_sock_domain == AF_INET6)) {
+                 // fill status
+-                state = "";
++                state = PSUTIL_CONN_NONE;
+                 if (kif->kf_sock_type == SOCK_STREAM) {
+                     tcp = psutil_search_tcplist(tcplist, kif);
+                     if (tcp != NULL)
+-                        state = get_connection_status((int)tcp->t_state);
++                        state = (int)tcp->t_state;
+                 }
+ 
+                 // build addr and port
+-                inet_ntop(kif->kf_sock_domain,
+-                    psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_local),
+-                    lip, sizeof(lip));
+-                inet_ntop(kif->kf_sock_domain,
+-                    psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_peer),
+-                    rip, sizeof(rip));
++                inet_ntop(
++                    kif->kf_sock_domain,
++                    psutil_sockaddr_addr(kif->kf_sock_domain,
++                                         &kif->kf_sa_local),
++                    lip,
++                    sizeof(lip));
++                inet_ntop(
++                    kif->kf_sock_domain,
++                    psutil_sockaddr_addr(kif->kf_sock_domain,
++                                         &kif->kf_sa_peer),
++                    rip,
++                    sizeof(rip));
+                 lport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
+                                                    &kif->kf_sa_local));
+                 rport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
+@@ -1098,20 +1092,19 @@
+                 laddr = Py_BuildValue("(si)", lip, lport);
+                 if (!laddr)
+                     goto error;
+-                if (rport != 0) {
++                if (rport != 0)
+                     raddr = Py_BuildValue("(si)", rip, rport);
+-                }
+-                else {
++                else
+                     raddr = Py_BuildValue("()");
+-                }
+                 if (!raddr)
+                     goto error;
+-                tuple = Py_BuildValue("(iiiNNs)", kif->kf_fd,
+-                                                  kif->kf_sock_domain,
+-                                                  kif->kf_sock_type,
+-                                                  laddr,
+-                                                  raddr,
+-                                                  state);
++                tuple = Py_BuildValue("(iiiNNi)",
++                                      kif->kf_fd,
++                                      kif->kf_sock_domain,
++                                      kif->kf_sock_type,
++                                      laddr,
++                                      raddr,
++                                      state);
+                 if (!tuple)
+                     goto error;
+                 if (PyList_Append(retList, tuple))
+@@ -1123,16 +1116,18 @@
+                 struct sockaddr_un *sun;
+ 
+                 sun = (struct sockaddr_un *)&kif->kf_sa_local;
+-                snprintf(path, sizeof(path), "%.*s",
+-                        (sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
+-                         sun->sun_path);
+-
+-                tuple = Py_BuildValue("(iiisOs)", kif->kf_fd,
+-                                                  kif->kf_sock_domain,
+-                                                  kif->kf_sock_type,
+-                                                  path,
+-                                                  Py_None,
+-                                                  "");
++                snprintf(
++                    path, sizeof(path), "%.*s",
++                    (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
++                    sun->sun_path);
++
++                tuple = Py_BuildValue("(iiisOi)",
++                                      kif->kf_fd,
++                                      kif->kf_sock_domain,
++                                      kif->kf_sock_type,
++                                      path,
++                                      Py_None,
++                                      PSUTIL_CONN_NONE);
+                 if (!tuple)
+                     goto error;
+                 if (PyList_Append(retList, tuple))
+@@ -1162,8 +1157,8 @@
+ /*
+  * Return a Python list of tuple representing per-cpu times
+  */
+-static PyObject*
+-get_system_per_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_per_cpu_times(PyObject *self, PyObject *args)
+ {
+     static int maxcpus;
+     int mib[2];
+@@ -1171,8 +1166,8 @@
+     size_t len;
+     size_t size;
+     int i;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_cputime = NULL;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_cputime = NULL;
+ 
+     if (py_retlist == NULL)
+         return NULL;
+@@ -1181,7 +1176,7 @@
+     size = sizeof(maxcpus);
+     if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
+         Py_DECREF(py_retlist);
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         return NULL;
+     }
+     long cpu_time[maxcpus][CPUSTATES];
+@@ -1191,25 +1186,25 @@
+     mib[1] = HW_NCPU;
+     len = sizeof(ncpu);
+     if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+     // per-cpu info
+     size = sizeof(cpu_time);
+     if (sysctlbyname("kern.cp_times", &cpu_time, &size, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+     for (i = 0; i < ncpu; i++) {
+-        py_cputime = Py_BuildValue("(ddddd)",
+-                               (double)cpu_time[i][CP_USER] / CLOCKS_PER_SEC,
+-                               (double)cpu_time[i][CP_NICE] / CLOCKS_PER_SEC,
+-                               (double)cpu_time[i][CP_SYS] / CLOCKS_PER_SEC,
+-                               (double)cpu_time[i][CP_IDLE] / CLOCKS_PER_SEC,
+-                               (double)cpu_time[i][CP_INTR] / CLOCKS_PER_SEC
+-                               );
++        py_cputime = Py_BuildValue(
++            "(ddddd)",
++            (double)cpu_time[i][CP_USER] / CLOCKS_PER_SEC,
++            (double)cpu_time[i][CP_NICE] / CLOCKS_PER_SEC,
++            (double)cpu_time[i][CP_SYS] / CLOCKS_PER_SEC,
++            (double)cpu_time[i][CP_IDLE] / CLOCKS_PER_SEC,
++            (double)cpu_time[i][CP_INTR] / CLOCKS_PER_SEC);
+         if (!py_cputime)
+             goto error;
+         if (PyList_Append(py_retlist, py_cputime))
+@@ -1233,38 +1228,36 @@
+     do
+         while (*p2 == ' ')
+             p2++;
+-    while (*p1++ = *p2++);
++    while ((*p1++ = *p2++));
+ }
+ 
++
+ /*
+  * Return a list of tuples for every process memory maps.
+  * 'procstat' cmdline utility has been used as an example.
+  */
+-static PyObject*
+-get_process_memory_maps(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_memory_maps(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int ptrwidth;
+     int i, cnt;
+-    char addr[30];
++    char addr[1000];
+     char perms[4];
+     const char *path;
+     struct kinfo_proc kp;
+     struct kinfo_vmentry *freep = NULL;
+     struct kinfo_vmentry *kve;
+-    ptrwidth = 2*sizeof(void *);
+-    PyObject* pytuple = NULL;
+-    PyObject* retlist = PyList_New(0);
++    ptrwidth = 2 * sizeof(void *);
++    PyObject *pytuple = NULL;
++    PyObject *retlist = PyList_New(0);
+ 
+-    if (retlist == NULL) {
++    if (retlist == NULL)
+         return NULL;
+-    }
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_kinfo_proc(pid, &kp) == -1)
+         goto error;
+-    }
+ 
+     freep = kinfo_getvmmap(pid, &cnt);
+     if (freep == NULL) {
+@@ -1277,7 +1270,7 @@
+         addr[0] = '\0';
+         perms[0] = '\0';
+         sprintf(addr, "%#*jx-%#*jx", ptrwidth, (uintmax_t)kve->kve_start,
+-                                     ptrwidth, (uintmax_t)kve->kve_end);
++                ptrwidth, (uintmax_t)kve->kve_end);
+         remove_spaces(addr);
+         strlcat(perms, kve->kve_protection & KVME_PROT_READ ? "r" : "-",
+                 sizeof(perms));
+@@ -1286,39 +1279,38 @@
+         strlcat(perms, kve->kve_protection & KVME_PROT_EXEC ? "x" : "-",
+                 sizeof(perms));
+ 
+-
+         if (strlen(kve->kve_path) == 0) {
+             switch (kve->kve_type) {
+-            case KVME_TYPE_NONE:
+-                path = "[none]";
+-                break;
+-            case KVME_TYPE_DEFAULT:
+-                path = "[default]";
+-                break;
+-            case KVME_TYPE_VNODE:
+-                path = "[vnode]";
+-                break;
+-            case KVME_TYPE_SWAP:
+-                path = "[swap]";
+-                break;
+-            case KVME_TYPE_DEVICE:
+-                path = "[device]";
+-                break;
+-            case KVME_TYPE_PHYS:
+-                path = "[phys]";
+-                break;
+-            case KVME_TYPE_DEAD:
+-                path = "[dead]";
+-                break;
+-            case KVME_TYPE_SG:
+-                path = "[sg]";
+-                break;
+-            case KVME_TYPE_UNKNOWN:
+-                path = "[unknown]";
+-                break;
+-            default:
+-                path = "[?]";
+-                break;
++                case KVME_TYPE_NONE:
++                    path = "[none]";
++                    break;
++                case KVME_TYPE_DEFAULT:
++                    path = "[default]";
++                    break;
++                case KVME_TYPE_VNODE:
++                    path = "[vnode]";
++                    break;
++                case KVME_TYPE_SWAP:
++                    path = "[swap]";
++                    break;
++                case KVME_TYPE_DEVICE:
++                    path = "[device]";
++                    break;
++                case KVME_TYPE_PHYS:
++                    path = "[phys]";
++                    break;
++                case KVME_TYPE_DEAD:
++                    path = "[dead]";
++                    break;
++                case KVME_TYPE_SG:
++                    path = "[sg]";
++                    break;
++                case KVME_TYPE_UNKNOWN:
++                    path = "[unknown]";
++                    break;
++                default:
++                    path = "[?]";
++                    break;
+             }
+         }
+         else {
+@@ -1332,8 +1324,7 @@
+             kve->kve_resident,          // rss
+             kve->kve_private_resident,  // private
+             kve->kve_ref_count,         // ref count
+-            kve->kve_shadow_count       // shadow count
+-        );
++            kve->kve_shadow_count);     // shadow count
+         if (!pytuple)
+             goto error;
+         if (PyList_Append(retlist, pytuple))
+@@ -1357,8 +1348,8 @@
+  * Return a list of tuples including device, mount point and fs type
+  * for all partitions mounted on the system.
+  */
+-static PyObject*
+-get_disk_partitions(PyObject* self, PyObject* args)
++static PyObject *
++psutil_disk_partitions(PyObject *self, PyObject *args)
+ {
+     int num;
+     int i;
+@@ -1366,8 +1357,8 @@
+     uint64_t flags;
+     char opts[200];
+     struct statfs *fs = NULL;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_tuple = NULL;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
+ 
+     if (py_retlist == NULL)
+         return NULL;
+@@ -1377,7 +1368,7 @@
+     num = getfsstat(NULL, 0, MNT_NOWAIT);
+     Py_END_ALLOW_THREADS
+     if (num == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1392,7 +1383,7 @@
+     num = getfsstat(fs, len, MNT_NOWAIT);
+     Py_END_ALLOW_THREADS
+     if (num == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1437,10 +1428,11 @@
+         if (flags & MNT_NFS4ACLS)
+             strlcat(opts, ",nfs4acls", sizeof(opts));
+ 
+-        py_tuple = Py_BuildValue("(ssss)", fs[i].f_mntfromname,  // device
+-                                           fs[i].f_mntonname,    // mount point
+-                                           fs[i].f_fstypename,   // fs type
+-                                           opts);                // options
++        py_tuple = Py_BuildValue("(ssss)",
++                                 fs[i].f_mntfromname,  // device
++                                 fs[i].f_mntonname,    // mount point
++                                 fs[i].f_fstypename,   // fs type
++                                 opts);                // options
+         if (!py_tuple)
+             goto error;
+         if (PyList_Append(py_retlist, py_tuple))
+@@ -1463,18 +1455,18 @@
+ /*
+  * Return a Python list of named tuples with overall network I/O information
+  */
+-static PyObject*
+-get_network_io_counters(PyObject* self, PyObject* args)
++static PyObject *
++psutil_net_io_counters(PyObject *self, PyObject *args)
+ {
+     char *buf = NULL, *lim, *next;
+     struct if_msghdr *ifm;
+     int mib[6];
+     size_t len;
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_ifc_info = NULL;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_ifc_info = NULL;
++
+     if (py_retdict == NULL)
+         return NULL;
+-
+     mib[0] = CTL_NET;          // networking subsystem
+     mib[1] = PF_ROUTE;         // type of information
+     mib[2] = 0;                // protocol (IPPROTO_xxx)
+@@ -1483,7 +1475,7 @@
+     mib[5] = 0;
+ 
+     if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1494,7 +1486,7 @@
+     }
+ 
+     if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1513,11 +1505,11 @@
+             strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
+             ifc_name[sdl->sdl_nlen] = 0;
+             // XXX: ignore usbus interfaces:
+-            // http://lists.freebsd.org/pipermail/freebsd-current/2011-October/028752.html
++            // http://lists.freebsd.org/pipermail/freebsd-current/
++            //     2011-October/028752.html
+             // 'ifconfig -a' doesn't show them, nor do we.
+-            if (strncmp(ifc_name, "usbus", 5) == 0) {
++            if (strncmp(ifc_name, "usbus", 5) == 0)
+                 continue;
+-            }
+ 
+             py_ifc_info = Py_BuildValue("(kkkkkkki)",
+                                         if2m->ifm_data.ifi_obytes,
+@@ -1554,17 +1546,17 @@
+ /*
+  * Return a Python dict of tuples for disk I/O information
+  */
+-static PyObject*
+-get_disk_io_counters(PyObject* self, PyObject* args)
++static PyObject *
++psutil_disk_io_counters(PyObject *self, PyObject *args)
+ {
+     int i;
+     struct statinfo stats;
+ 
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_disk_info = NULL;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_disk_info = NULL;
++
+     if (py_retdict == NULL)
+         return NULL;
+-
+     if (devstat_checkversion(NULL) < 0) {
+         PyErr_Format(PyExc_RuntimeError, "devstat_checkversion() failed");
+         goto error;
+@@ -1588,10 +1580,11 @@
+         char disk_name[128];
+         current = stats.dinfo->devices[i];
+         snprintf(disk_name, sizeof(disk_name), "%s%d",
+-                                current.device_name,
+-                                current.unit_number);
++                 current.device_name,
++                 current.unit_number);
+ 
+-        py_disk_info = Py_BuildValue("(KKKKLL)",
++        py_disk_info = Py_BuildValue(
++            "(KKKKLL)",
+             current.operations[DEVSTAT_READ],   // no reads
+             current.operations[DEVSTAT_WRITE],  // no writes
+             current.bytes[DEVSTAT_READ],        // bytes read
+@@ -1599,8 +1592,7 @@
+             (long long)devstat_compute_etime(
+                 &current.duration[DEVSTAT_READ], NULL),  // r time
+             (long long)devstat_compute_etime(
+-                &current.duration[DEVSTAT_WRITE], NULL)  // w time
+-        );
++                &current.duration[DEVSTAT_WRITE], NULL));  // w time
+         if (!py_disk_info)
+             goto error;
+         if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
+@@ -1608,9 +1600,8 @@
+         Py_DECREF(py_disk_info);
+     }
+ 
+-    if (stats.dinfo->mem_ptr) {
++    if (stats.dinfo->mem_ptr)
+         free(stats.dinfo->mem_ptr);
+-    }
+     free(stats.dinfo);
+     return py_retdict;
+ 
+@@ -1626,8 +1617,8 @@
+ /*
+  * Return currently connected users as a list of tuples.
+  */
+-static PyObject*
+-get_system_users(PyObject* self, PyObject* args)
++static PyObject *
++psutil_users(PyObject *self, PyObject *args)
+ {
+     PyObject *ret_list = PyList_New(0);
+     PyObject *tuple = NULL;
+@@ -1641,19 +1632,19 @@
+ 
+     fp = fopen(_PATH_UTMP, "r");
+     if (fp == NULL) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+     while (fread(&ut, sizeof(ut), 1, fp) == 1) {
+         if (*ut.ut_name == '\0')
+             continue;
+-        tuple = Py_BuildValue("(sssf)",
+-            ut.ut_name,              // username
+-            ut.ut_line,              // tty
+-            ut.ut_host,              // hostname
+-            (float)ut.ut_time        // start time
+-        );
++        tuple = Py_BuildValue(
++            "(sssf)",
++            ut.ut_name,         // username
++            ut.ut_line,         // tty
++            ut.ut_host,         // hostname
++           (float)ut.ut_time);  // start time
+         if (!tuple) {
+             fclose(fp);
+             goto error;
+@@ -1672,12 +1663,14 @@
+     while ((utx = getutxent()) != NULL) {
+         if (utx->ut_type != USER_PROCESS)
+             continue;
+-        tuple = Py_BuildValue("(sssf)",
+-            utx->ut_user,             // username
+-            utx->ut_line,             // tty
+-            utx->ut_host,             // hostname
++        tuple = Py_BuildValue(
++            "(sssf)",
++            utx->ut_user,  // username
++            utx->ut_line,  // tty
++            utx->ut_host,  // hostname
+             (float)utx->ut_tv.tv_sec  // start time
+         );
++
+         if (!tuple) {
+             endutxent();
+             goto error;
+@@ -1700,87 +1693,523 @@
+ }
+ 
+ 
++
++/*
++ * System-wide open connections.
++ */
++
++#define HASHSIZE 1009
++static struct xfile *psutil_xfiles;
++static int psutil_nxfiles;
++
++int
++psutil_populate_xfiles()
++{
++    size_t len;
++
++    if ((psutil_xfiles = malloc(len = sizeof *psutil_xfiles)) == NULL) {
++        PyErr_NoMemory();
++        return 0;
++    }
++    while (sysctlbyname("kern.file", psutil_xfiles, &len, 0, 0) == -1) {
++        if (errno != ENOMEM) {
++            PyErr_SetFromErrno(0);
++            return 0;
++        }
++        len *= 2;
++        if ((psutil_xfiles = realloc(psutil_xfiles, len)) == NULL) {
++            PyErr_NoMemory();
++            return 0;
++        }
++    }
++    if (len > 0 && psutil_xfiles->xf_size != sizeof *psutil_xfiles) {
++        PyErr_Format(PyExc_RuntimeError, "struct xfile size mismatch");
++        return 0;
++    }
++    psutil_nxfiles = len / sizeof *psutil_xfiles;
++    return 1;
++}
++
++int
++psutil_get_pid_from_sock(int sock_hash)
++{
++    struct xfile *xf;
++    int hash, n;
++    for (xf = psutil_xfiles, n = 0; n < psutil_nxfiles; ++n, ++xf) {
++        if (xf->xf_data == NULL)
++            continue;
++        hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
++        if (sock_hash == hash)
++            return xf->xf_pid;
++    }
++    return -1;
++}
++
++
++// Reference:
++// https://gitorious.org/freebsd/freebsd/source/
++//     f1d6f4778d2044502209708bc167c05f9aa48615:usr.bin/sockstat/sockstat.c
++int psutil_gather_inet(int proto, PyObject *py_retlist)
++{
++    struct xinpgen *xig, *exig;
++    struct xinpcb *xip;
++    struct xtcpcb *xtp;
++    struct inpcb *inp;
++    struct xsocket *so;
++    const char *varname = NULL;
++    size_t len, bufsize;
++    void *buf;
++    int hash;
++    int retry;
++    int type;
++
++    PyObject *tuple = NULL;
++    PyObject *laddr = NULL;
++    PyObject *raddr = NULL;
++
++    switch (proto) {
++        case IPPROTO_TCP:
++            varname = "net.inet.tcp.pcblist";
++            type = SOCK_STREAM;
++            break;
++        case IPPROTO_UDP:
++            varname = "net.inet.udp.pcblist";
++            type = SOCK_DGRAM;
++            break;
++    }
++
++    buf = NULL;
++    bufsize = 8192;
++    retry = 5;
++    do {
++        for (;;) {
++            buf = realloc(buf, bufsize);
++            if (buf == NULL)
++                continue;  // XXX
++            len = bufsize;
++            if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
++                break;
++            if (errno != ENOMEM) {
++                PyErr_SetFromErrno(0);
++                goto error;
++            }
++            bufsize *= 2;
++        }
++        xig = (struct xinpgen *)buf;
++        exig = (struct xinpgen *)(void *)((char *)buf + len - sizeof *exig);
++        if (xig->xig_len != sizeof *xig || exig->xig_len != sizeof *exig) {
++            PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
++            goto error;
++        }
++    } while (xig->xig_gen != exig->xig_gen && retry--);
++
++
++    for (;;) {
++        int lport, rport, pid, status, family;
++
++        xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
++        if (xig >= exig)
++            break;
++
++        switch (proto) {
++            case IPPROTO_TCP:
++                xtp = (struct xtcpcb *)xig;
++                if (xtp->xt_len != sizeof *xtp) {
++                    PyErr_Format(PyExc_RuntimeError,
++                                 "struct xtcpcb size mismatch");
++                    goto error;
++                }
++                inp = &xtp->xt_inp;
++                so = &xtp->xt_socket;
++                status = xtp->xt_tp.t_state;
++                break;
++            case IPPROTO_UDP:
++                xip = (struct xinpcb *)xig;
++                if (xip->xi_len != sizeof *xip) {
++                    PyErr_Format(PyExc_RuntimeError,
++                                 "struct xinpcb size mismatch");
++                    goto error;
++                }
++                inp = &xip->xi_inp;
++                so = &xip->xi_socket;
++                status = PSUTIL_CONN_NONE;
++                break;
++            default:
++                PyErr_Format(PyExc_RuntimeError, "invalid proto");
++                goto error;
++        }
++
++        char lip[200], rip[200];
++
++        hash = (int)((uintptr_t)so->xso_so % HASHSIZE);
++        pid = psutil_get_pid_from_sock(hash);
++        if (pid < 0)
++            continue;
++        lport = ntohs(inp->inp_lport);
++        rport = ntohs(inp->inp_fport);
++
++        if (inp->inp_vflag & INP_IPV4) {
++            family = AF_INET;
++            inet_ntop(AF_INET, &inp->inp_laddr.s_addr, lip, sizeof(lip));
++            inet_ntop(AF_INET, &inp->inp_faddr.s_addr, rip, sizeof(rip));
++        }
++        else if (inp->inp_vflag & INP_IPV6) {
++            family = AF_INET6;
++            inet_ntop(AF_INET6, &inp->in6p_laddr.s6_addr, lip, sizeof(lip));
++            inet_ntop(AF_INET6, &inp->in6p_faddr.s6_addr, rip, sizeof(rip));
++        }
++
++        // construct python tuple/list
++        laddr = Py_BuildValue("(si)", lip, lport);
++        if (!laddr)
++            goto error;
++        if (rport != 0)
++            raddr = Py_BuildValue("(si)", rip, rport);
++        else
++            raddr = Py_BuildValue("()");
++        if (!raddr)
++            goto error;
++        tuple = Py_BuildValue("(iiiNNii)", -1, family, type, laddr, raddr,
++                                               status, pid);
++        if (!tuple)
++            goto error;
++        if (PyList_Append(py_retlist, tuple))
++            goto error;
++        Py_DECREF(tuple);
++    }
++
++    free(buf);
++    return 1;
++
++error:
++    Py_XDECREF(tuple);
++    Py_XDECREF(laddr);
++    Py_XDECREF(raddr);
++    free(buf);
++    return 0;
++}
++
++
++int psutil_gather_unix(int proto, PyObject *py_retlist)
++{
++    struct xunpgen *xug, *exug;
++    struct xunpcb *xup;
++    const char *varname = NULL;
++    const char *protoname = NULL;
++    size_t len;
++    size_t bufsize;
++    void *buf;
++    int hash;
++    int retry;
++    int pid;
++    struct sockaddr_un *sun;
++    char path[PATH_MAX];
++
++    PyObject *tuple = NULL;
++    PyObject *laddr = NULL;
++    PyObject *raddr = NULL;
++
++    switch (proto) {
++        case SOCK_STREAM:
++            varname = "net.local.stream.pcblist";
++            protoname = "stream";
++            break;
++        case SOCK_DGRAM:
++            varname = "net.local.dgram.pcblist";
++            protoname = "dgram";
++            break;
++    }
++
++    buf = NULL;
++    bufsize = 8192;
++    retry = 5;
++
++    do {
++        for (;;) {
++            buf = realloc(buf, bufsize);
++            if (buf == NULL) {
++                PyErr_NoMemory();
++                goto error;
++            }
++            len = bufsize;
++            if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
++                break;
++            if (errno != ENOMEM) {
++                PyErr_SetFromErrno(0);
++                goto error;
++            }
++            bufsize *= 2;
++        }
++        xug = (struct xunpgen *)buf;
++        exug = (struct xunpgen *)(void *)
++            ((char *)buf + len - sizeof *exug);
++        if (xug->xug_len != sizeof *xug || exug->xug_len != sizeof *exug) {
++            PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
++            goto error;
++        }
++    } while (xug->xug_gen != exug->xug_gen && retry--);
++
++    for (;;) {
++        xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
++        if (xug >= exug)
++            break;
++        xup = (struct xunpcb *)xug;
++        if (xup->xu_len != sizeof *xup)
++            goto error;
++
++        hash = (int)((uintptr_t) xup->xu_socket.xso_so % HASHSIZE);
++        pid = psutil_get_pid_from_sock(hash);
++        if (pid < 0)
++            continue;
++
++        sun = (struct sockaddr_un *)&xup->xu_addr;
++        snprintf(path, sizeof(path), "%.*s",
++                 (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
++                 sun->sun_path);
++
++        tuple = Py_BuildValue("(iiisOii)", -1, AF_UNIX, proto, path, Py_None,
++                                               PSUTIL_CONN_NONE, pid);
++        if (!tuple)
++            goto error;
++        if (PyList_Append(py_retlist, tuple))
++            goto error;
++        Py_DECREF(tuple);
++        Py_INCREF(Py_None);
++    }
++
++    free(buf);
++    return 1;
++
++error:
++    Py_XDECREF(tuple);
++    Py_XDECREF(laddr);
++    Py_XDECREF(raddr);
++    free(buf);
++    return 0;
++}
++
++
++/*
++ * Return system-wide open connections.
++ */
++static PyObject*
++psutil_net_connections(PyObject* self, PyObject* args)
++{
++    PyObject *py_retlist = PyList_New(0);
++
++    if (py_retlist == NULL)
++        return NULL;
++    if (psutil_populate_xfiles() != 1)
++        goto error;
++    if (psutil_gather_inet(IPPROTO_TCP, py_retlist) == 0)
++        goto error;
++    if (psutil_gather_inet(IPPROTO_UDP, py_retlist) == 0)
++        goto error;
++    if (psutil_gather_unix(SOCK_STREAM, py_retlist) == 0)
++       goto error;
++    if (psutil_gather_unix(SOCK_DGRAM, py_retlist) == 0)
++        goto error;
++
++    free(psutil_xfiles);
++    return py_retlist;
++
++error:
++    Py_DECREF(py_retlist);
++    free(psutil_xfiles);
++    return NULL;
++}
++
++
++/*
++ * Get process CPU affinity.
++ * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c
++ */
++static PyObject*
++psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args)
++{
++    long pid;
++    int ret;
++    int i;
++    cpuset_t mask;
++    PyObject* py_retlist;
++    PyObject* py_cpu_num;
++
++    if (!PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
++                             sizeof(mask), &mask);
++    if (ret != 0) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        return NULL;
++    }
++
++    py_retlist = PyList_New(0);
++    if (py_retlist == NULL)
++        return NULL;
++
++    for (i = 0; i < CPU_SETSIZE; i++) {
++        if (CPU_ISSET(i, &mask)) {
++            py_cpu_num = Py_BuildValue("i", i);
++            if (py_cpu_num == NULL)
++                goto error;
++            if (PyList_Append(py_retlist, py_cpu_num))
++                goto error;
++        }
++    }
++
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_cpu_num);
++    Py_DECREF(py_retlist);
++    return NULL;
++}
++
++
++/*
++ * Set process CPU affinity.
++ * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c
++ */
++static PyObject *
++psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
++{
++    long pid;
++    int i;
++    int seq_len;
++    int ret;
++    cpuset_t cpu_set;
++    PyObject *py_cpu_set;
++    PyObject *py_cpu_seq = NULL;
++
++    if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
++        return NULL;
++
++    py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer");
++    if (!py_cpu_seq)
++        return NULL;
++    seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);
++
++    // calculate the mask
++    CPU_ZERO(&cpu_set);
++    for (i = 0; i < seq_len; i++) {
++        PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i);
++#if PY_MAJOR_VERSION >= 3
++        long value = PyLong_AsLong(item);
++#else
++        long value = PyInt_AsLong(item);
++#endif
++        if (value == -1 && PyErr_Occurred())
++            goto error;
++        CPU_SET(value, &cpu_set);
++    }
++
++    // set affinity
++    ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
++                             sizeof(cpu_set), &cpu_set);
++    if (ret != 0) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    Py_DECREF(py_cpu_seq);
++    Py_RETURN_NONE;
++
++error:
++    if (py_cpu_seq != NULL)
++        Py_DECREF(py_cpu_seq);
++    return NULL;
++}
++
++
+ /*
+  * define the psutil C module methods and initialize the module.
+  */
+ static PyMethodDef
+ PsutilMethods[] =
+ {
+-     // --- per-process functions
++    // --- per-process functions
+ 
+-     {"get_process_name", get_process_name, METH_VARARGS,
+-        "Return process name"},
+-     {"get_process_connections", get_process_connections, METH_VARARGS,
+-        "Return connections opened by process"},
+-     {"get_process_exe", get_process_exe, METH_VARARGS,
+-        "Return process pathname executable"},
+-     {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
+-        "Return process cmdline as a list of cmdline arguments"},
+-     {"get_process_ppid", get_process_ppid, METH_VARARGS,
+-        "Return process ppid as an integer"},
+-     {"get_process_uids", get_process_uids, METH_VARARGS,
+-        "Return process real effective and saved user ids as a Python tuple"},
+-     {"get_process_gids", get_process_gids, METH_VARARGS,
+-        "Return process real effective and saved group ids as a Python tuple"},
+-     {"get_process_cpu_times", get_process_cpu_times, METH_VARARGS,
+-           "Return tuple of user/kern time for the given PID"},
+-     {"get_process_create_time", get_process_create_time, METH_VARARGS,
+-         "Return a float indicating the process create time expressed in "
+-         "seconds since the epoch"},
+-     {"get_process_memory_info", get_process_memory_info, METH_VARARGS,
+-         "Return extended memory info for a process as a Python tuple."},
+-     {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
+-         "Return number of threads used by process"},
+-     {"get_process_num_ctx_switches", get_process_num_ctx_switches, METH_VARARGS,
+-         "Return the number of context switches performed by process"},
+-     {"get_process_threads", get_process_threads, METH_VARARGS,
+-         "Return process threads"},
+-     {"get_process_status", get_process_status, METH_VARARGS,
+-         "Return process status as an integer"},
+-     {"get_process_io_counters", get_process_io_counters, METH_VARARGS,
+-         "Return process IO counters"},
+-     {"get_process_tty_nr", get_process_tty_nr, METH_VARARGS,
+-         "Return process tty (terminal) number"},
++    {"proc_name", psutil_proc_name, METH_VARARGS,
++     "Return process name"},
++    {"proc_connections", psutil_proc_connections, METH_VARARGS,
++     "Return connections opened by process"},
++    {"proc_exe", psutil_proc_exe, METH_VARARGS,
++     "Return process pathname executable"},
++    {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
++     "Return process cmdline as a list of cmdline arguments"},
++    {"proc_ppid", psutil_proc_ppid, METH_VARARGS,
++     "Return process ppid as an integer"},
++    {"proc_uids", psutil_proc_uids, METH_VARARGS,
++     "Return process real effective and saved user ids as a Python tuple"},
++    {"proc_gids", psutil_proc_gids, METH_VARARGS,
++     "Return process real effective and saved group ids as a Python tuple"},
++    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
++     "Return tuple of user/kern time for the given PID"},
++    {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
++     "Return a float indicating the process create time expressed in "
++     "seconds since the epoch"},
++    {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
++     "Return extended memory info for a process as a Python tuple."},
++    {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS,
++     "Return number of threads used by process"},
++    {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
++     "Return the number of context switches performed by process"},
++    {"proc_threads", psutil_proc_threads, METH_VARARGS,
++     "Return process threads"},
++    {"proc_status", psutil_proc_status, METH_VARARGS,
++     "Return process status as an integer"},
++    {"proc_io_counters", psutil_proc_io_counters, METH_VARARGS,
++     "Return process IO counters"},
++    {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS,
++     "Return process tty (terminal) number"},
++    {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
++     "Return process CPU affinity."},
++    {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
++     "Set process CPU affinity."},
+ #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+-     {"get_process_open_files", get_process_open_files, METH_VARARGS,
+-         "Return files opened by process as a list of (path, fd) tuples"},
+-     {"get_process_cwd", get_process_cwd, METH_VARARGS,
+-         "Return process current working directory."},
+-     {"get_process_memory_maps", get_process_memory_maps, METH_VARARGS,
+-         "Return a list of tuples for every process's memory map"},
+-     {"get_process_num_fds", get_process_num_fds, METH_VARARGS,
+-         "Return the number of file descriptors opened by this process"},
++    {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
++     "Return files opened by process as a list of (path, fd) tuples"},
++    {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
++     "Return process current working directory."},
++    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
++     "Return a list of tuples for every process's memory map"},
++    {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS,
++     "Return the number of file descriptors opened by this process"},
+ #endif
+ 
+-     // --- system-related functions
++    // --- system-related functions
+ 
+-     {"get_pid_list", get_pid_list, METH_VARARGS,
+-         "Returns a list of PIDs currently running on the system"},
+-     {"get_num_cpus", get_num_cpus, METH_VARARGS,
+-           "Return number of CPUs on the system"},
+-     {"get_virtual_mem", get_virtual_mem, METH_VARARGS,
+-         "Return system virtual memory usage statistics"},
+-     {"get_swap_mem", get_swap_mem, METH_VARARGS,
+-         "Return swap mem stats"},
+-     {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
+-         "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
++    {"pids", psutil_pids, METH_VARARGS,
++     "Returns a list of PIDs currently running on the system"},
++    {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
++     "Return number of logical CPUs on the system"},
++    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
++     "Return an XML string to determine the number physical CPUs."},
++    {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
++     "Return system virtual memory usage statistics"},
++    {"swap_mem", psutil_swap_mem, METH_VARARGS,
++     "Return swap mem stats"},
++    {"cpu_times", psutil_cpu_times, METH_VARARGS,
++     "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
+ #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+-     {"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS,
+-         "Return system per-cpu times as a list of tuples"},
++    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
++     "Return system per-cpu times as a list of tuples"},
+ #endif
+-     {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
+-         "Return the system boot time expressed in seconds since the epoch."},
+-     {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
+-         "Return a list of tuples including device, mount point and "
+-         "fs type for all partitions mounted on the system."},
+-     {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
+-         "Return dict of tuples of networks I/O information."},
+-     {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
+-         "Return a Python dict of tuples for disk I/O information"},
+-     {"get_system_users", get_system_users, METH_VARARGS,
+-        "Return currently connected users as a list of tuples"},
++    {"boot_time", psutil_boot_time, METH_VARARGS,
++     "Return the system boot time expressed in seconds since the epoch."},
++    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
++     "Return a list of tuples including device, mount point and "
++     "fs type for all partitions mounted on the system."},
++    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
++     "Return dict of tuples of networks I/O information."},
++    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
++     "Return a Python dict of tuples for disk I/O information"},
++    {"users", psutil_users, METH_VARARGS,
++     "Return currently connected users as a list of tuples"},
++    {"net_connections", psutil_net_connections, METH_VARARGS,
++     "Return system-wide open connections."},
+ 
+-     {NULL, NULL, 0, NULL}
++    {NULL, NULL, 0, NULL}
+ };
+ 
+ struct module_state {
+@@ -1808,22 +2237,21 @@
+ }
+ 
+ static struct PyModuleDef
+-moduledef = {
+-        PyModuleDef_HEAD_INIT,
+-        "psutil_bsd",
+-        NULL,
+-        sizeof(struct module_state),
+-        PsutilMethods,
+-        NULL,
+-        psutil_bsd_traverse,
+-        psutil_bsd_clear,
+-        NULL
++        moduledef = {
++    PyModuleDef_HEAD_INIT,
++    "psutil_bsd",
++    NULL,
++    sizeof(struct module_state),
++    PsutilMethods,
++    NULL,
++    psutil_bsd_traverse,
++    psutil_bsd_clear,
++    NULL
+ };
+ 
+ #define INITERROR return NULL
+ 
+-PyObject *
+-PyInit__psutil_bsd(void)
++PyMODINIT_FUNC PyInit__psutil_bsd(void)
+ 
+ #else
+ #define INITERROR return
+@@ -1836,6 +2264,9 @@
+ #else
+     PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods);
+ #endif
++    PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
++
++    // process status constants
+     PyModule_AddIntConstant(module, "SSTOP", SSTOP);
+     PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+     PyModule_AddIntConstant(module, "SRUN", SRUN);
+@@ -1843,10 +2274,22 @@
+     PyModule_AddIntConstant(module, "SWAIT", SWAIT);
+     PyModule_AddIntConstant(module, "SLOCK", SLOCK);
+     PyModule_AddIntConstant(module, "SZOMB", SZOMB);
++    // connection status constants
++    PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
++    PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
++    PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
++    PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
++    PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
++    PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
++    PyModule_AddIntConstant(module, "TCPS_SYN_RECEIVED", TCPS_SYN_RECEIVED);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
++    PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
++    PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
++    PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
+ 
+-    if (module == NULL) {
++    if (module == NULL)
+         INITERROR;
+-    }
+ #if PY_MAJOR_VERSION >= 3
+     return module;
+ #endif
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_bsd.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_bsd.h	2015-06-17 19:33:33.000000000 -0700
+@@ -1,50 +1,53 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * BSD platform-specific module methods for _psutil_bsd
+  */
+ 
+ #include <Python.h>
+ 
+ // --- per-process functions
+ 
+-static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* get_process_name(PyObject* self, PyObject* args);
+-static PyObject* get_process_exe(PyObject* self, PyObject* args);
+-static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
+-static PyObject* get_process_ppid(PyObject* self, PyObject* args);
+-static PyObject* get_process_uids(PyObject* self, PyObject* args);
+-static PyObject* get_process_gids(PyObject* self, PyObject* args);
+-static PyObject* get_process_connections(PyObject* self, PyObject* args);
+-static PyObject* get_process_create_time(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_fds(PyObject* self, PyObject* args);
+-static PyObject* get_process_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_status(PyObject* self, PyObject* args);
+-static PyObject* get_process_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_process_tty_nr(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_ctx_switches(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_connections(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_gids(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_ctx_switches(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_ppid(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_status(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_tty_nr(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_uids(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
++
+ #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+-static PyObject* get_process_open_files(PyObject* self, PyObject* args);
+-static PyObject* get_process_cwd(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
+ #endif
+ 
+ // --- system-related functions
+ 
+-static PyObject* get_pid_list(PyObject* self, PyObject* args);
+-static PyObject* get_num_cpus(PyObject* self, PyObject* args);
+-static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
+-static PyObject* get_swap_mem(PyObject* self, PyObject* args);
+-static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
++static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_pids(PyObject* self, PyObject* args);
++static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
++static PyObject* psutil_users(PyObject* self, PyObject* args);
++static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
++
+ #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
+-static PyObject* get_system_per_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
+ #endif
+-static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
+-static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
+-static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_system_users(PyObject* self, PyObject* args);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_common.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_common.c	2015-06-17 19:33:33.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+@@ -22,6 +22,7 @@
+     return NULL;
+ }
+ 
++
+ /*
+  * Set OSError(errno=EACCES, strerror="Permission denied") Python exception.
+  */
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_common.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_common.h	2015-06-17 19:33:33.000000000 -0700
+@@ -1,11 +1,10 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  */
+ 
+ #include <Python.h>
+ 
+-PyObject* NoSuchProcess(void);
+ PyObject* AccessDenied(void);
+-
++PyObject* NoSuchProcess(void);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_linux.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_linux.c	2015-06-17 19:33:33.000000000 -0700
+@@ -1,31 +1,62 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+  * Linux-specific functions.
+  */
+ 
++#ifndef _GNU_SOURCE
++    #define _GNU_SOURCE 1
++#endif
+ #include <Python.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <mntent.h>
++#include <features.h>
+ #include <utmp.h>
+ #include <sched.h>
++#include <linux/version.h>
+ #include <sys/syscall.h>
+ #include <sys/sysinfo.h>
+-#include <linux/unistd.h>
++#include <sys/ioctl.h>
++#include <sys/socket.h>
++#include <linux/sockios.h>
++#include <linux/if.h>
++#include <linux/ethtool.h>
+ 
+ #include "_psutil_linux.h"
+ 
++/* The minimum number of CPUs allocated in a cpu_set_t */
++static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
++
++// Linux >= 2.6.13
++#define PSUTIL_HAVE_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
+ 
+-#define HAS_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set)
++// Linux >= 2.6.36 (supposedly) and glibc >= 13
++#define PSUTIL_HAVE_PRLIMIT \
++    (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && \
++    (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 13) && \
++    defined(__NR_prlimit64)
++
++#if PSUTIL_HAVE_PRLIMIT
++    #define _FILE_OFFSET_BITS 64
++    #include <time.h>
++    #include <sys/resource.h>
++#endif
+ 
+-#if HAS_IOPRIO
++
++#if PSUTIL_HAVE_IOPRIO
+ enum {
+     IOPRIO_WHO_PROCESS = 1,
+ };
+ 
++// May happen on old RedHat versions, see:
++// https://github.com/giampaolo/psutil/issues/607
++#ifndef DUPLEX_UNKNOWN
++    #define DUPLEX_UNKNOWN 0xff
++#endif
++
+ static inline int
+ ioprio_get(int which, int who)
+ {
+@@ -38,29 +69,27 @@
+     return syscall(__NR_ioprio_set, which, who, ioprio);
+ }
+ 
+-#define IOPRIO_CLASS_SHIFT  13
+-#define IOPRIO_PRIO_MASK  ((1UL << IOPRIO_CLASS_SHIFT) - 1)
++#define IOPRIO_CLASS_SHIFT 13
++#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+ 
+-#define IOPRIO_PRIO_CLASS(mask)  ((mask) >> IOPRIO_CLASS_SHIFT)
+-#define IOPRIO_PRIO_DATA(mask)  ((mask) & IOPRIO_PRIO_MASK)
+-#define IOPRIO_PRIO_VALUE(class, data)  (((class) << IOPRIO_CLASS_SHIFT) | data)
++#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
++#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
++#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+ 
+ 
+ /*
+  * Return a (ioclass, iodata) Python tuple representing process I/O priority.
+  */
+-static PyObject*
+-linux_ioprio_get(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_ioprio_get(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int ioprio, ioclass, iodata;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+     ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
+-    if (ioprio == -1) {
++    if (ioprio == -1)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+     ioclass = IOPRIO_PRIO_CLASS(ioprio);
+     iodata = IOPRIO_PRIO_DATA(ioprio);
+     return Py_BuildValue("ii", ioclass, iodata);
+@@ -72,23 +101,81 @@
+  * ioclass can be either IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE
+  * or 0. iodata goes from 0 to 7 depending on ioclass specified.
+  */
+-static PyObject*
+-linux_ioprio_set(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_ioprio_set(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int ioprio, ioclass, iodata;
+     int retval;
+ 
+-    if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata)) {
++    if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata))
+         return NULL;
+-    }
+     ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata);
+     retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio);
+-    if (retval == -1) {
++    if (retval == -1)
+         return PyErr_SetFromErrno(PyExc_OSError);
++    Py_RETURN_NONE;
++}
++#endif
++
++
++#if PSUTIL_HAVE_PRLIMIT
++/*
++ * A wrapper around prlimit(2); sets process resource limits.
++ * This can be used for both get and set, in which case extra
++ * 'soft' and 'hard' args must be provided.
++ */
++static PyObject *
++psutil_linux_prlimit(PyObject *self, PyObject *args)
++{
++    long pid;
++    int ret, resource;
++    struct rlimit old, new;
++    struct rlimit *newp = NULL;
++    PyObject *soft = NULL;
++    PyObject *hard = NULL;
++
++    if (! PyArg_ParseTuple(args, "li|OO", &pid, &resource, &soft, &hard))
++        return NULL;
++
++    // get
++    if (soft == NULL && hard == NULL) {
++        ret = prlimit(pid, resource, NULL, &old);
++        if (ret == -1)
++            return PyErr_SetFromErrno(PyExc_OSError);
++#if defined(PSUTIL_HAVE_LONG_LONG)
++        if (sizeof(old.rlim_cur) > sizeof(long)) {
++            return Py_BuildValue("LL",
++                                 (PY_LONG_LONG)old.rlim_cur,
++                                 (PY_LONG_LONG)old.rlim_max);
++        }
++#endif
++        return Py_BuildValue("ll", (long)old.rlim_cur, (long)old.rlim_max);
++    }
++
++    // set
++    else {
++#if defined(PSUTIL_HAVE_LARGEFILE_SUPPORT)
++        new.rlim_cur = PyLong_AsLongLong(soft);
++        if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
++            return NULL;
++        new.rlim_max = PyLong_AsLongLong(hard);
++        if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
++            return NULL;
++#else
++        new.rlim_cur = PyLong_AsLong(soft);
++        if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
++            return NULL;
++        new.rlim_max = PyLong_AsLong(hard);
++        if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
++            return NULL;
++#endif
++        newp = &new;
++        ret = prlimit(pid, resource, newp, &old);
++        if (ret == -1)
++            return PyErr_SetFromErrno(PyExc_OSError);
++        Py_RETURN_NONE;
+     }
+-    Py_INCREF(Py_None);
+-    return Py_None;
+ }
+ #endif
+ 
+@@ -97,13 +184,13 @@
+  * Return disk mounted partitions as a list of tuples including device,
+  * mount point and filesystem type
+  */
+-static PyObject*
+-get_disk_partitions(PyObject* self, PyObject* args)
++static PyObject *
++psutil_disk_partitions(PyObject *self, PyObject *args)
+ {
+     FILE *file = NULL;
+     struct mntent *entry;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_tuple = NULL;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
+ 
+     if (py_retlist == NULL)
+         return NULL;
+@@ -113,7 +200,7 @@
+     file = setmntent(MOUNTED, "r");
+     Py_END_ALLOW_THREADS
+     if ((file == 0) || (file == NULL)) {
+-        PyErr_SetFromErrno(PyExc_OSError);
++        PyErr_SetFromErrnoWithFilename(PyExc_OSError, MOUNTED);
+         goto error;
+     }
+ 
+@@ -122,10 +209,11 @@
+             PyErr_Format(PyExc_RuntimeError, "getmntent() failed");
+             goto error;
+         }
+-        py_tuple = Py_BuildValue("(ssss)", entry->mnt_fsname,  // device
+-                                           entry->mnt_dir,     // mount point
+-                                           entry->mnt_type,    // fs type
+-                                           entry->mnt_opts);   // options
++        py_tuple = Py_BuildValue("(ssss)",
++                                 entry->mnt_fsname,  // device
++                                 entry->mnt_dir,     // mount point
++                                 entry->mnt_type,    // fs type
++                                 entry->mnt_opts);   // options
+         if (! py_tuple)
+             goto error;
+         if (PyList_Append(py_retlist, py_tuple))
+@@ -147,16 +235,16 @@
+ /*
+  * A wrapper around sysinfo(), return system memory usage statistics.
+  */
+-static PyObject*
+-get_sysinfo(PyObject* self, PyObject* args)
++static PyObject *
++psutil_linux_sysinfo(PyObject *self, PyObject *args)
+ {
+     struct sysinfo info;
+-    if (sysinfo(&info) != 0) {
+-        return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+ 
+-    // note: BOOT_TIME might also be determined from here
+-    return Py_BuildValue("(KKKKKK)",
++    if (sysinfo(&info) != 0)
++        return PyErr_SetFromErrno(PyExc_OSError);
++    // note: boot time might also be determined from here
++    return Py_BuildValue(
++        "(KKKKKK)",
+         (unsigned long long)info.totalram  * info.mem_unit,   // total
+         (unsigned long long)info.freeram   * info.mem_unit,   // free
+         (unsigned long long)info.bufferram * info.mem_unit,   // buffer
+@@ -167,51 +255,179 @@
+ 
+ 
+ /*
+- * Return process CPU affinity as a Python long (the bitmask)
++ * Return process CPU affinity as a Python list
++ * The dual implementation exists because of:
++ * https://github.com/giampaolo/psutil/issues/536
+  */
+-static PyObject*
+-get_process_cpu_affinity(PyObject* self, PyObject* args)
++
++#ifdef CPU_ALLOC
++
++static PyObject *
++psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
+ {
+-    unsigned long mask;
+-    unsigned int len = sizeof(mask);
++    int cpu, ncpus, count, cpucount_s;
+     long pid;
++    size_t setsize;
++    cpu_set_t *mask = NULL;
++    PyObject *res = NULL;
+ 
+-    if (!PyArg_ParseTuple(args, "i", &pid)) {
++    if (!PyArg_ParseTuple(args, "i", &pid))
+         return NULL;
++    ncpus = NCPUS_START;
++    while (1) {
++        setsize = CPU_ALLOC_SIZE(ncpus);
++        mask = CPU_ALLOC(ncpus);
++        if (mask == NULL)
++            return PyErr_NoMemory();
++        if (sched_getaffinity(pid, setsize, mask) == 0)
++            break;
++        CPU_FREE(mask);
++        if (errno != EINVAL)
++            return PyErr_SetFromErrno(PyExc_OSError);
++        if (ncpus > INT_MAX / 2) {
++            PyErr_SetString(PyExc_OverflowError, "could not allocate "
++                            "a large enough CPU set");
++            return NULL;
++        }
++        ncpus = ncpus * 2;
+     }
+-    if (sched_getaffinity(pid, len, (cpu_set_t *)&mask) < 0) {
+-        return PyErr_SetFromErrno(PyExc_OSError);
++
++    res = PyList_New(0);
++    if (res == NULL)
++        goto error;
++
++    cpucount_s = CPU_COUNT_S(setsize, mask);
++    for (cpu = 0, count = cpucount_s; count; cpu++) {
++        if (CPU_ISSET_S(cpu, setsize, mask)) {
++#if PY_MAJOR_VERSION >= 3
++            PyObject *cpu_num = PyLong_FromLong(cpu);
++#else
++            PyObject *cpu_num = PyInt_FromLong(cpu);
++#endif
++            if (cpu_num == NULL)
++                goto error;
++            if (PyList_Append(res, cpu_num)) {
++                Py_DECREF(cpu_num);
++                goto error;
++            }
++            Py_DECREF(cpu_num);
++            --count;
++        }
+     }
+-    return Py_BuildValue("l", mask);
++    CPU_FREE(mask);
++    return res;
++
++error:
++    if (mask)
++        CPU_FREE(mask);
++    Py_XDECREF(res);
++    return NULL;
+ }
++#else
+ 
+ 
+ /*
++ * Alternative implementation in case CPU_ALLOC is not defined.
++ */
++static PyObject *
++psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
++{
++    cpu_set_t cpuset;
++    unsigned int len = sizeof(cpu_set_t);
++    long pid;
++    int i;
++    PyObject* py_retlist = NULL;
++    PyObject *py_cpu_num = NULL;
++
++    if (!PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++	CPU_ZERO(&cpuset);
++    if (sched_getaffinity(pid, len, &cpuset) < 0)
++        return PyErr_SetFromErrno(PyExc_OSError);
++
++    py_retlist = PyList_New(0);
++    if (py_retlist == NULL)
++        goto error;
++    for (i = 0; i < CPU_SETSIZE; ++i) {
++        if (CPU_ISSET(i, &cpuset)) {
++            py_cpu_num = Py_BuildValue("i", i);
++            if (py_cpu_num == NULL)
++                goto error;
++            if (PyList_Append(py_retlist, py_cpu_num))
++                goto error;
++            Py_DECREF(py_cpu_num);
++        }
++    }
++
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_cpu_num);
++    Py_DECREF(py_retlist);
++    return NULL;
++}
++#endif
++
++/*
+  * Set process CPU affinity; expects a bitmask
+  */
+-static PyObject*
+-set_process_cpu_affinity(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
+ {
+-    unsigned long mask;
+-    unsigned int len = sizeof(mask);
++    cpu_set_t cpu_set;
++    size_t len;
+     long pid;
++    int i, seq_len;
++    PyObject *py_cpu_set;
++    PyObject *py_cpu_seq = NULL;
+ 
+-    if (!PyArg_ParseTuple(args, "ll", &pid, &mask)) {
++    if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
+         return NULL;
++
++    if (!PySequence_Check(py_cpu_set)) {
++        PyErr_Format(PyExc_TypeError, "sequence argument expected, got %s",
++                     Py_TYPE(py_cpu_set)->tp_name);
++        goto error;
+     }
+-    if (sched_setaffinity(pid, len, (cpu_set_t *)&mask)) {
+-        return PyErr_SetFromErrno(PyExc_OSError);
++
++    py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer");
++    if (!py_cpu_seq)
++        goto error;
++    seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);
++    CPU_ZERO(&cpu_set);
++    for (i = 0; i < seq_len; i++) {
++        PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i);
++#if PY_MAJOR_VERSION >= 3
++        long value = PyLong_AsLong(item);
++#else
++        long value = PyInt_AsLong(item);
++#endif
++        if (value == -1 && PyErr_Occurred())
++            goto error;
++        CPU_SET(value, &cpu_set);
+     }
+-    Py_INCREF(Py_None);
+-    return Py_None;
++
++    len = sizeof(cpu_set);
++    if (sched_setaffinity(pid, len, &cpu_set)) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    Py_DECREF(py_cpu_seq);
++    Py_RETURN_NONE;
++
++error:
++    if (py_cpu_seq != NULL)
++        Py_DECREF(py_cpu_seq);
++    return NULL;
+ }
+ 
+ 
+ /*
+  * Return currently connected users as a list of tuples.
+  */
+-static PyObject*
+-get_system_users(PyObject* self, PyObject* args)
++static PyObject *
++psutil_users(PyObject *self, PyObject *args)
+ {
+     PyObject *ret_list = PyList_New(0);
+     PyObject *tuple = NULL;
+@@ -220,7 +436,6 @@
+ 
+     if (ret_list == NULL)
+         return NULL;
+-
+     setutent();
+     while (NULL != (ut = getutent())) {
+         tuple = NULL;
+@@ -229,14 +444,15 @@
+             user_proc = Py_True;
+         else
+             user_proc = Py_False;
+-        tuple = Py_BuildValue("(sssfO)",
++        tuple = Py_BuildValue(
++            "(sssfO)",
+             ut->ut_user,              // username
+             ut->ut_line,              // tty
+             ut->ut_host,              // hostname
+             (float)ut->ut_tv.tv_sec,  // tstamp
+             user_proc                 // (bool) user process
+         );
+-        if (! tuple)
++    if (! tuple)
+             goto error;
+         if (PyList_Append(ret_list, tuple))
+             goto error;
+@@ -255,30 +471,126 @@
+ 
+ 
+ /*
++ * Return stats about a particular network
++ * interface.  References:
++ * https://github.com/dpaleino/wicd/blob/master/wicd/backends/be-ioctl.py
++ * http://www.i-scream.org/libstatgrab/
++ */
++static PyObject*
++psutil_net_if_stats(PyObject* self, PyObject* args)
++{
++    char *nic_name;
++    int sock = 0;
++    int ret;
++    int duplex;
++    int speed;
++    int mtu;
++    struct ifreq ifr;
++    struct ethtool_cmd ethcmd;
++    PyObject *py_is_up = NULL;
++    PyObject *py_ret = NULL;
++
++    if (! PyArg_ParseTuple(args, "s", &nic_name))
++        return NULL;
++
++    sock = socket(AF_INET, SOCK_DGRAM, 0);
++    if (sock == -1)
++        goto error;
++    strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
++
++    // is up?
++    ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
++    if (ret == -1)
++        goto error;
++    if ((ifr.ifr_flags & IFF_UP) != 0)
++        py_is_up = Py_True;
++    else
++        py_is_up = Py_False;
++    Py_INCREF(py_is_up);
++
++    // MTU
++    ret = ioctl(sock, SIOCGIFMTU, &ifr);
++    if (ret == -1)
++        goto error;
++    mtu = ifr.ifr_mtu;
++
++    // duplex and speed
++    memset(&ethcmd, 0, sizeof ethcmd);
++    ethcmd.cmd = ETHTOOL_GSET;
++    ifr.ifr_data = (caddr_t)&ethcmd;
++    ret = ioctl(sock, SIOCETHTOOL, &ifr);
++
++    if (ret != -1) {
++        duplex = ethcmd.duplex;
++        speed = ethcmd.speed;
++    }
++    else {
++        if (errno == EOPNOTSUPP) {
++            // we typically get here in case of wi-fi cards
++            duplex = DUPLEX_UNKNOWN;
++            speed = 0;
++        }
++        else {
++            goto error;
++        }
++    }
++
++    close(sock);
++    py_ret = Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu);
++    if (!py_ret)
++        goto error;
++    Py_DECREF(py_is_up);
++    return py_ret;
++
++error:
++    Py_XDECREF(py_is_up);
++    if (sock != 0)
++        close(sock);
++    PyErr_SetFromErrno(PyExc_OSError);
++    return NULL;
++}
++
++
++/*
+  * Define the psutil C module methods and initialize the module.
+  */
+ static PyMethodDef
+ PsutilMethods[] =
+ {
+-#if HAS_IOPRIO
+-     {"ioprio_get", linux_ioprio_get, METH_VARARGS,
+-        "Get process I/O priority"},
+-     {"ioprio_set", linux_ioprio_set, METH_VARARGS,
+-        "Set process I/O priority"},
+-#endif
+-     {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
+-        "Return disk mounted partitions as a list of tuples including "
+-        "device, mount point and filesystem type"},
+-     {"get_sysinfo", get_sysinfo, METH_VARARGS,
+-        "A wrapper around sysinfo(), return system memory usage statistics"},
+-     {"get_process_cpu_affinity", get_process_cpu_affinity, METH_VARARGS,
+-        "Return process CPU affinity as a Python long (the bitmask)."},
+-     {"set_process_cpu_affinity", set_process_cpu_affinity, METH_VARARGS,
+-        "Set process CPU affinity; expects a bitmask."},
+-     {"get_system_users", get_system_users, METH_VARARGS,
+-        "Return currently connected users as a list of tuples"},
++    // --- per-process functions
++
++#if PSUTIL_HAVE_IOPRIO
++    {"proc_ioprio_get", psutil_proc_ioprio_get, METH_VARARGS,
++     "Get process I/O priority"},
++    {"proc_ioprio_set", psutil_proc_ioprio_set, METH_VARARGS,
++     "Set process I/O priority"},
++#endif
++    {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
++     "Return process CPU affinity as a Python long (the bitmask)."},
++    {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
++     "Set process CPU affinity; expects a bitmask."},
++
++    // --- system related functions
++
++    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
++     "Return disk mounted partitions as a list of tuples including "
++     "device, mount point and filesystem type"},
++    {"users", psutil_users, METH_VARARGS,
++     "Return currently connected users as a list of tuples"},
++    {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
++     "Return NIC stats (isup, duplex, speed, mtu)"},
++
++    // --- linux specific
++
++    {"linux_sysinfo", psutil_linux_sysinfo, METH_VARARGS,
++     "A wrapper around sysinfo(), return system memory usage statistics"},
++#if PSUTIL_HAVE_PRLIMIT
++    {"linux_prlimit", psutil_linux_prlimit, METH_VARARGS,
++     "Get or set process resource limits."},
++#endif
++
+ 
+-     {NULL, NULL, 0, NULL}
++    {NULL, NULL, 0, NULL}
+ };
+ 
+ struct module_state {
+@@ -306,22 +618,21 @@
+ }
+ 
+ static struct PyModuleDef
+-moduledef = {
+-        PyModuleDef_HEAD_INIT,
+-        "psutil_linux",
+-        NULL,
+-        sizeof(struct module_state),
+-        PsutilMethods,
+-        NULL,
+-        psutil_linux_traverse,
+-        psutil_linux_clear,
+-        NULL
++        moduledef = {
++    PyModuleDef_HEAD_INIT,
++    "psutil_linux",
++    NULL,
++    sizeof(struct module_state),
++    PsutilMethods,
++    NULL,
++    psutil_linux_traverse,
++    psutil_linux_clear,
++    NULL
+ };
+ 
+ #define INITERROR return NULL
+ 
+-PyObject *
+-PyInit__psutil_linux(void)
++PyMODINIT_FUNC PyInit__psutil_linux(void)
+ 
+ #else
+ #define INITERROR return
+@@ -334,9 +645,44 @@
+ #else
+     PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods);
+ #endif
+-    if (module == NULL) {
++
++
++    PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
++#if PSUTIL_HAVE_PRLIMIT
++    PyModule_AddIntConstant(module, "RLIM_INFINITY", RLIM_INFINITY);
++    PyModule_AddIntConstant(module, "RLIMIT_AS", RLIMIT_AS);
++    PyModule_AddIntConstant(module, "RLIMIT_CORE", RLIMIT_CORE);
++    PyModule_AddIntConstant(module, "RLIMIT_CPU", RLIMIT_CPU);
++    PyModule_AddIntConstant(module, "RLIMIT_DATA", RLIMIT_DATA);
++    PyModule_AddIntConstant(module, "RLIMIT_FSIZE", RLIMIT_FSIZE);
++    PyModule_AddIntConstant(module, "RLIMIT_LOCKS", RLIMIT_LOCKS);
++    PyModule_AddIntConstant(module, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
++    PyModule_AddIntConstant(module, "RLIMIT_NOFILE", RLIMIT_NOFILE);
++    PyModule_AddIntConstant(module, "RLIMIT_NPROC", RLIMIT_NPROC);
++    PyModule_AddIntConstant(module, "RLIMIT_RSS", RLIMIT_RSS);
++    PyModule_AddIntConstant(module, "RLIMIT_STACK", RLIMIT_STACK);
++#ifdef RLIMIT_MSGQUEUE
++    PyModule_AddIntConstant(module, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
++#endif
++#ifdef RLIMIT_NICE
++    PyModule_AddIntConstant(module, "RLIMIT_NICE", RLIMIT_NICE);
++#endif
++#ifdef RLIMIT_RTPRIO
++    PyModule_AddIntConstant(module, "RLIMIT_RTPRIO", RLIMIT_RTPRIO);
++#endif
++#ifdef RLIMIT_RTTIME
++    PyModule_AddIntConstant(module, "RLIMIT_RTTIME", RLIMIT_RTTIME);
++#endif
++#ifdef RLIMIT_SIGPENDING
++    PyModule_AddIntConstant(module, "RLIMIT_SIGPENDING", RLIMIT_SIGPENDING);
++#endif
++#endif
++    PyModule_AddIntConstant(module, "DUPLEX_HALF", DUPLEX_HALF);
++    PyModule_AddIntConstant(module, "DUPLEX_FULL", DUPLEX_FULL);
++    PyModule_AddIntConstant(module, "DUPLEX_UNKNOWN", DUPLEX_UNKNOWN);
++
++    if (module == NULL)
+         INITERROR;
+-    }
+ #if PY_MAJOR_VERSION >= 3
+     return module;
+ #endif
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_linux.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_linux.h	2015-06-17 19:33:33.000000000 -0700
+@@ -1,17 +1,21 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * LINUX specific module methods for _psutil_linux
+  */
+ 
+ #include <Python.h>
+ 
+-static PyObject* linux_ioprio_get(PyObject* self, PyObject* args);
+-static PyObject* linux_ioprio_set(PyObject* self, PyObject* args);
+-static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
+-static PyObject* get_sysinfo(PyObject* self, PyObject* args);
+-static PyObject* get_process_cpu_affinity(PyObject* self, PyObject* args);
+-static PyObject* set_process_cpu_affinity(PyObject* self, PyObject* args);
+-static PyObject* get_system_users(PyObject* self, PyObject* args);
++// process
++
++static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_ioprio_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_ioprio_get(PyObject* self, PyObject* args);
++
++// system
++
++static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
++static PyObject* psutil_linux_sysinfo(PyObject* self, PyObject* args);
++static PyObject* psutil_users(PyObject* self, PyObject* args);
++static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_mswindows.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_mswindows.c	1969-12-31 16:00:00.000000000 -0800
+@@ -1,3083 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Windows platform-specific module methods for _psutil_mswindows
+- */
+-
+-// Fixes clash between winsock2.h and windows.h
+-#define WIN32_LEAN_AND_MEAN
+-
+-#include <Python.h>
+-#include <windows.h>
+-#include <Psapi.h>
+-#include <time.h>
+-#include <lm.h>
+-#include <WinIoCtl.h>
+-#include <tchar.h>
+-#include <tlhelp32.h>
+-#include <winsock2.h>
+-#include <iphlpapi.h>
+-#include <wtsapi32.h>
+-
+-// Link with Iphlpapi.lib
+-#pragma comment(lib, "IPHLPAPI.lib")
+-
+-#include "_psutil_mswindows.h"
+-#include "_psutil_common.h"
+-#include "arch/mswindows/security.h"
+-#include "arch/mswindows/process_info.h"
+-#include "arch/mswindows/process_handles.h"
+-#include "arch/mswindows/ntextapi.h"
+-
+-
+-/*
+- * Return a Python float representing the system uptime expressed in seconds
+- * since the epoch.
+- */
+-static PyObject*
+-get_system_boot_time(PyObject* self, PyObject* args)
+-{
+-    double uptime;
+-    time_t pt;
+-    FILETIME fileTime;
+-    long long ll;
+-
+-    GetSystemTimeAsFileTime(&fileTime);
+-
+-    /*
+-    HUGE thanks to:
+-    http://johnstewien.spaces.live.com/blog/cns!E6885DB5CEBABBC8!831.entry
+-
+-    This function converts the FILETIME structure to the 32 bit
+-    Unix time structure.
+-    The time_t is a 32-bit value for the number of seconds since
+-    January 1, 1970. A FILETIME is a 64-bit for the number of
+-    100-nanosecond periods since January 1, 1601. Convert by
+-    subtracting the number of 100-nanosecond period betwee 01-01-1970
+-    and 01-01-1601, from time_t the divide by 1e+7 to get to the same
+-    base granularity.
+-    */
+-    ll = (((LONGLONG)(fileTime.dwHighDateTime)) << 32) + fileTime.dwLowDateTime;
+-    pt = (time_t)((ll - 116444736000000000ull) / 10000000ull);
+-
+-    // XXX - By using GetTickCount() time will wrap around to zero if the
+-    // system is run continuously for 49.7 days.
+-    uptime = GetTickCount() / 1000.00f;
+-    return Py_BuildValue("d", (double)pt - uptime);
+-}
+-
+-
+-/*
+- * Return 1 if PID exists in the current process list, else 0.
+- */
+-static PyObject*
+-pid_exists(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    int status;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    status = psutil_pid_is_running(pid);
+-    if (-1 == status) {
+-        return NULL; // exception raised in psutil_pid_is_running()
+-    }
+-    return PyBool_FromLong(status);
+-}
+-
+-
+-/*
+- * Return a Python list of all the PIDs running on the system.
+- */
+-static PyObject*
+-get_pid_list(PyObject* self, PyObject* args)
+-{
+-    DWORD *proclist = NULL;
+-    DWORD numberOfReturnedPIDs;
+-    DWORD i;
+-    PyObject* pid = NULL;
+-    PyObject* retlist = PyList_New(0);
+-
+-    if (retlist == NULL) {
+-        return NULL;
+-    }
+-    proclist = psutil_get_pids(&numberOfReturnedPIDs);
+-    if (NULL == proclist) {
+-        goto error;
+-    }
+-
+-    for (i = 0; i < numberOfReturnedPIDs; i++) {
+-        pid = Py_BuildValue("I", proclist[i]);
+-        if (!pid)
+-            goto error;
+-        if (PyList_Append(retlist, pid))
+-            goto error;
+-        Py_DECREF(pid);
+-    }
+-
+-    // free C array allocated for PIDs
+-    free(proclist);
+-    return retlist;
+-
+-error:
+-    Py_XDECREF(pid);
+-    Py_DECREF(retlist);
+-    if (proclist != NULL)
+-        free(proclist);
+-    return NULL;
+-}
+-
+-
+-/*
+- * Kill a process given its PID.
+- */
+-static PyObject*
+-kill_process(PyObject* self, PyObject* args)
+-{
+-    HANDLE hProcess;
+-    long pid;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (pid == 0) {
+-        return AccessDenied();
+-    }
+-
+-    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+-    if (hProcess == NULL) {
+-        if (GetLastError() == ERROR_INVALID_PARAMETER) {
+-            // see http://code.google.com/p/psutil/issues/detail?id=24
+-            NoSuchProcess();
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-        }
+-        return NULL;
+-    }
+-
+-    // kill the process
+-    if (! TerminateProcess(hProcess, 0)) {
+-        PyErr_SetFromWindowsErr(0);
+-        CloseHandle(hProcess);
+-        return NULL;
+-    }
+-
+-    CloseHandle(hProcess);
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-
+-
+-/*
+- * Wait for process to terminate and return its exit code.
+- */
+-static PyObject*
+-process_wait(PyObject* self, PyObject* args)
+-{
+-    HANDLE hProcess;
+-    DWORD ExitCode;
+-    DWORD retVal;
+-    long pid;
+-    long timeout;
+-
+-    if (! PyArg_ParseTuple(args, "ll", &pid, &timeout)) {
+-        return NULL;
+-    }
+-    if (pid == 0) {
+-        return AccessDenied();
+-    }
+-
+-    hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);
+-    if (hProcess == NULL) {
+-        if (GetLastError() == ERROR_INVALID_PARAMETER) {
+-            // no such process; we do not want to raise NSP but
+-            // return None instead.
+-            Py_INCREF(Py_None);
+-            return Py_None;
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-            return NULL;
+-        }
+-    }
+-
+-    // wait until the process has terminated
+-    Py_BEGIN_ALLOW_THREADS
+-    retVal = WaitForSingleObject(hProcess, timeout);
+-    Py_END_ALLOW_THREADS
+-
+-    if (retVal == WAIT_FAILED) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(GetLastError());
+-    }
+-    if (retVal == WAIT_TIMEOUT) {
+-        CloseHandle(hProcess);
+-        return Py_BuildValue("l", WAIT_TIMEOUT);
+-    }
+-
+-    // get the exit code; note: subprocess module (erroneously?) uses
+-    // what returned by WaitForSingleObject
+-    if (GetExitCodeProcess(hProcess, &ExitCode) == 0) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(GetLastError());
+-    }
+-    CloseHandle(hProcess);
+-#if PY_MAJOR_VERSION >= 3
+-    return PyLong_FromLong((long) ExitCode);
+-#else
+-    return PyInt_FromLong((long) ExitCode);
+-#endif
+-}
+-
+-
+-/*
+- * Return a Python tuple (user_time, kernel_time)
+- */
+-static PyObject*
+-get_process_cpu_times(PyObject* self, PyObject* args)
+-{
+-    long        pid;
+-    HANDLE      hProcess;
+-    FILETIME    ftCreate, ftExit, ftKernel, ftUser;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
+-        CloseHandle(hProcess);
+-        if (GetLastError() == ERROR_ACCESS_DENIED) {
+-            // usually means the process has died so we throw a NoSuchProcess
+-            // here
+-            return NoSuchProcess();
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-            return NULL;
+-        }
+-    }
+-
+-    CloseHandle(hProcess);
+-
+-    /*
+-    user and kernel times are represented as a FILETIME structure wich contains
+-    a 64-bit value representing the number of 100-nanosecond intervals since
+-    January 1, 1601 (UTC).
+-    http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
+-
+-    To convert it into a float representing the seconds that the process has
+-    executed in user/kernel mode I borrowed the code below from Python's
+-    Modules/posixmodule.c
+-    */
+-
+-    return Py_BuildValue(
+-        "(dd)",
+-        (double)(ftUser.dwHighDateTime*429.4967296 + \
+-                 ftUser.dwLowDateTime*1e-7),
+-        (double)(ftKernel.dwHighDateTime*429.4967296 + \
+-                 ftKernel.dwLowDateTime*1e-7)
+-        );
+-}
+-
+-
+-/*
+- * Alternative implementation of the one above but bypasses ACCESS DENIED.
+- */
+-static PyObject*
+-get_process_cpu_times_2(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    double user, kernel;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    user = (double)process->UserTime.HighPart * 429.4967296 + \
+-           (double)process->UserTime.LowPart * 1e-7;
+-    kernel = (double)process->KernelTime.HighPart * 429.4967296 + \
+-             (double)process->KernelTime.LowPart * 1e-7;
+-    free(buffer);
+-    return Py_BuildValue("(dd)", user, kernel);
+-}
+-
+-
+-/*
+- * Return a Python float indicating the process create time expressed in
+- * seconds since the epoch.
+- */
+-static PyObject*
+-get_process_create_time(PyObject* self, PyObject* args)
+-{
+-    long        pid;
+-    long long   unix_time;
+-    DWORD       exitCode;
+-    HANDLE      hProcess;
+-    BOOL        ret;
+-    FILETIME    ftCreate, ftExit, ftKernel, ftUser;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    // special case for PIDs 0 and 4, return BOOT_TIME
+-    if (0 == pid || 4 == pid) {
+-        return get_system_boot_time(NULL, NULL);
+-    }
+-
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
+-        CloseHandle(hProcess);
+-        if (GetLastError() == ERROR_ACCESS_DENIED) {
+-            // usually means the process has died so we throw a NoSuchProcess here
+-            return NoSuchProcess();
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-            return NULL;
+-        }
+-    }
+-
+-    // Make sure the process is not gone as OpenProcess alone seems to be
+-    // unreliable in doing so (it seems a previous call to p.wait() makes
+-    // it unreliable).
+-    // This check is important as creation time is used to make sure the
+-    // process is still running.
+-    ret = GetExitCodeProcess(hProcess, &exitCode);
+-    CloseHandle(hProcess);
+-    if (ret != 0) {
+-        if (exitCode != STILL_ACTIVE) {
+-            return NoSuchProcess();
+-        }
+-    }
+-    else {
+-        // Ignore access denied as it means the process is still alive.
+-        // For all other errors, we want an exception.
+-        if (GetLastError() != ERROR_ACCESS_DENIED) {
+-            PyErr_SetFromWindowsErr(0);
+-            return NULL;
+-        }
+-    }
+-
+-    /*
+-    Convert the FILETIME structure to a Unix time.
+-    It's the best I could find by googling and borrowing code here and there.
+-    The time returned has a precision of 1 second.
+-    */
+-    unix_time = ((LONGLONG)ftCreate.dwHighDateTime) << 32;
+-    unix_time += ftCreate.dwLowDateTime - 116444736000000000LL;
+-    unix_time /= 10000000;
+-    return Py_BuildValue("d", (double)unix_time);
+-}
+-
+-
+-/*
+- * Alternative implementation of the one above but bypasses ACCESS DENIED.
+- */
+-static PyObject*
+-get_process_create_time_2(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    long long   unix_time;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    // special case for PIDs 0 and 4, return BOOT_TIME
+-    if (0 == pid || 4 == pid) {
+-        return get_system_boot_time(NULL, NULL);
+-    }
+-    /*
+-    Convert the LARGE_INTEGER union to a Unix time.
+-    It's the best I could find by googling and borrowing code here and there.
+-    The time returned has a precision of 1 second.
+-    */
+-    unix_time = ((LONGLONG)process->CreateTime.HighPart) << 32;
+-    unix_time += process->CreateTime.LowPart - 116444736000000000LL;
+-    unix_time /= 10000000;
+-    free(buffer);
+-    return Py_BuildValue("d", (double)unix_time);
+-}
+-
+-
+-/*
+- * Return a Python integer indicating the number of CPUs on the system.
+- */
+-static PyObject*
+-get_num_cpus(PyObject* self, PyObject* args)
+-{
+-    SYSTEM_INFO system_info;
+-    system_info.dwNumberOfProcessors = 0;
+-
+-    GetSystemInfo(&system_info);
+-    if (system_info.dwNumberOfProcessors == 0){
+-        // GetSystemInfo failed for some reason; return 1 as default
+-        return Py_BuildValue("I", 1);
+-    }
+-    return Py_BuildValue("I", system_info.dwNumberOfProcessors);
+-}
+-
+-/*
+- * Return process name as a Python string.
+- */
+-static PyObject*
+-get_process_name(PyObject* self, PyObject* args) {
+-    long pid;
+-    int pid_return;
+-    PyObject* name;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    if (pid == 0) {
+-        return Py_BuildValue("s", "System Idle Process");
+-    }
+-    else if (pid == 4) {
+-        return Py_BuildValue("s", "System");
+-    }
+-
+-    pid_return = psutil_pid_is_running(pid);
+-    if (pid_return == 0) {
+-        return NoSuchProcess();
+-    }
+-    if (pid_return == -1) {
+-        return NULL;
+-    }
+-
+-    name = psutil_get_name(pid);
+-    if (name == NULL) {
+-        return NULL;  // exception set in psutil_get_name()
+-    }
+-    return name;
+-}
+-
+-
+-/*
+- * Return process parent pid as a Python integer.
+- */
+-static PyObject*
+-get_process_ppid(PyObject* self, PyObject* args) {
+-    long pid;
+-    int pid_return;
+-    PyObject* ppid;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if ((pid == 0) || (pid == 4)) {
+-        return Py_BuildValue("l", 0);
+-    }
+-
+-    pid_return = psutil_pid_is_running(pid);
+-    if (pid_return == 0) {
+-        return NoSuchProcess();
+-    }
+-    if (pid_return == -1) {
+-        return NULL;
+-    }
+-
+-    ppid = psutil_get_ppid(pid);
+-    if (ppid == NULL) {
+-        return NULL;  // exception set in psutil_get_ppid()
+-    }
+-    return ppid;
+-}
+-
+-/*
+- * Return process cmdline as a Python list of cmdline arguments.
+- */
+-static PyObject*
+-get_process_cmdline(PyObject* self, PyObject* args) {
+-    long pid;
+-    int pid_return;
+-    PyObject* arglist;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if ((pid == 0) || (pid == 4)) {
+-        return Py_BuildValue("[]");
+-    }
+-
+-    pid_return = psutil_pid_is_running(pid);
+-    if (pid_return == 0) {
+-        return NoSuchProcess();
+-    }
+-    if (pid_return == -1) {
+-        return NULL;
+-    }
+-
+-    // XXX the assumptio below probably needs to go away
+-
+-    // May fail any of several ReadProcessMemory calls etc. and not indicate
+-    // a real problem so we ignore any errors and just live without commandline
+-    arglist = psutil_get_arg_list(pid);
+-    if ( NULL == arglist ) {
+-        // carry on anyway, clear any exceptions too
+-        PyErr_Clear();
+-        return Py_BuildValue("[]");
+-    }
+-
+-    return arglist;
+-}
+-
+-
+-/*
+- * Return process executable path.
+- */
+-static PyObject*
+-get_process_exe(PyObject* self, PyObject* args) {
+-    long pid;
+-    HANDLE hProcess;
+-    wchar_t exe[MAX_PATH];
+-    DWORD nSize = MAX_PATH;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
+-    if (NULL == hProcess) {
+-        return NULL;
+-    }
+-
+-    if (GetProcessImageFileName(hProcess, &exe, nSize) == 0) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    CloseHandle(hProcess);
+-    return Py_BuildValue("s", exe);
+-}
+-
+-
+-/*
+- * Return process memory information as a Python tuple.
+- */
+-static PyObject*
+-get_process_memory_info(PyObject* self, PyObject* args)
+-{
+-    HANDLE hProcess;
+-    DWORD pid;
+-#if (_WIN32_WINNT >= 0x0501)  // Windows XP with SP2
+-    PROCESS_MEMORY_COUNTERS_EX cnt;
+-#else
+-    PROCESS_MEMORY_COUNTERS cnt;
+-#endif
+-    SIZE_T private = 0;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (NULL == hProcess) {
+-        return NULL;
+-    }
+-
+-    if (! GetProcessMemoryInfo(hProcess, &cnt, sizeof(cnt)) ) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-#if (_WIN32_WINNT >= 0x0501)
+-    private = cnt.PrivateUsage;
+-#endif
+-
+-    CloseHandle(hProcess);
+-
+-// py 2.4
+-#if (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION <= 4)
+-    return Py_BuildValue("(kIIIIIIIII)",
+-        cnt.PageFaultCount,
+-        (unsigned int)cnt.PeakWorkingSetSize,
+-        (unsigned int)cnt.WorkingSetSize,
+-        (unsigned int)cnt.QuotaPeakPagedPoolUsage,
+-        (unsigned int)cnt.QuotaPagedPoolUsage,
+-        (unsigned int)cnt.QuotaPeakNonPagedPoolUsage,
+-        (unsigned int)cnt.QuotaNonPagedPoolUsage,
+-        (unsigned int)cnt.PagefileUsage,
+-        (unsigned int)cnt.PeakPagefileUsage,
+-        (unsigned int)private);
+-#else
+-// py >= 2.5
+-    return Py_BuildValue("(knnnnnnnnn)",
+-        cnt.PageFaultCount,
+-        cnt.PeakWorkingSetSize,
+-        cnt.WorkingSetSize,
+-        cnt.QuotaPeakPagedPoolUsage,
+-        cnt.QuotaPagedPoolUsage,
+-        cnt.QuotaPeakNonPagedPoolUsage,
+-        cnt.QuotaNonPagedPoolUsage,
+-        cnt.PagefileUsage,
+-        cnt.PeakPagefileUsage,
+-        private);
+-#endif
+-}
+-
+-
+-/*
+- * Alternative implementation of the one above but bypasses ACCESS DENIED.
+- */
+-static PyObject*
+-get_process_memory_info_2(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    ULONG m0;
+-    SIZE_T m1, m2, m3, m4, m5, m6, m7, m8, m9;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    m0 = process->PageFaultCount;
+-    m1 = process->PeakWorkingSetSize;
+-    m2 = process->WorkingSetSize;
+-    m3 = process->QuotaPeakPagedPoolUsage;
+-    m4 = process->QuotaPagedPoolUsage;
+-    m5 = process->QuotaPeakNonPagedPoolUsage;
+-    m6 = process->QuotaNonPagedPoolUsage;
+-    m7 = process->PagefileUsage;
+-    m8 = process->PeakPagefileUsage;
+-#if (_WIN32_WINNT >= 0x0501)
+-    m9 = process->PrivatePageCount;  // private me
+-#else
+-    m9 = 0;
+-#endif
+-    free(buffer);
+-
+-// py 2.4
+-#if (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION <= 4)
+-    return Py_BuildValue("(kIIIIIIIII)",
+-        (unsigned int)m0, (unsigned int)m1, (unsigned int)m2, (unsigned int)m3,
+-        (unsigned int)m4, (unsigned int)m5, (unsigned int)m6, (unsigned int)m7,
+-        (unsigned int)m8, (unsigned int)m9);
+-#else
+-    return Py_BuildValue("(knnnnnnnnn)",
+-        m0, m1, m2, m3, m4, m5, m6, m7, m8, m9);
+-#endif
+-}
+-
+-
+-/*
+- * Return a Python integer indicating the total amount of physical memory
+- * in bytes.
+- */
+-static PyObject*
+-get_virtual_mem(PyObject* self, PyObject* args)
+-{
+-    MEMORYSTATUSEX memInfo;
+-    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+-
+-    if (! GlobalMemoryStatusEx(&memInfo) ) {
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    return Py_BuildValue("(LLLLLL)",
+-        memInfo.ullTotalPhys,      // total
+-        memInfo.ullAvailPhys,      // avail
+-        memInfo.ullTotalPageFile,  // total page file
+-        memInfo.ullAvailPageFile,  // avail page file
+-        memInfo.ullTotalVirtual,   // total virtual
+-        memInfo.ullAvailVirtual    // avail virtual
+-    );
+-}
+-
+-
+-#define LO_T ((float)1e-7)
+-#define HI_T (LO_T*4294967296.0)
+-
+-
+-/*
+- * Return a Python list of tuples representing user, kernel and idle
+- * CPU times for every CPU on the system.
+- */
+-static PyObject*
+-get_system_cpu_times(PyObject* self, PyObject* args)
+-{
+-    float idle, kernel, user;
+-    typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
+-    NTQSI_PROC NtQuerySystemInformation;
+-    HINSTANCE hNtDll;
+-    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
+-    SYSTEM_INFO si;
+-    UINT i;
+-    PyObject *arg = NULL;
+-    PyObject *retlist = PyList_New(0);
+-
+-    if (retlist == NULL)
+-        return NULL;
+-
+-    // dynamic linking is mandatory to use NtQuerySystemInformation
+-    hNtDll = LoadLibrary(TEXT("ntdll.dll"));
+-    if (hNtDll != NULL) {
+-        // gets NtQuerySystemInformation address
+-        NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
+-                                    hNtDll, "NtQuerySystemInformation");
+-
+-        if (NtQuerySystemInformation != NULL)
+-        {
+-            // retrives number of processors
+-            GetSystemInfo(&si);
+-
+-            // allocates an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
+-            // structures, one per processor
+-            sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
+-                    malloc(si.dwNumberOfProcessors * \
+-                         sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
+-            if (sppi != NULL)
+-            {
+-                // gets cpu time informations
+-                if (0 == NtQuerySystemInformation(
+-                    SystemProcessorPerformanceInformation,
+-                    sppi,
+-                    si.dwNumberOfProcessors * sizeof
+-                                (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
+-                    NULL)
+-                )
+-                {
+-                    // computes system global times summing each processor value
+-                    idle = user = kernel = 0;
+-                    for (i=0; i<si.dwNumberOfProcessors; i++) {
+-                        arg = NULL;
+-                        user = (float)((HI_T * sppi[i].UserTime.HighPart) + \
+-                                       (LO_T * sppi[i].UserTime.LowPart));
+-                        idle = (float)((HI_T * sppi[i].IdleTime.HighPart) + \
+-                                       (LO_T * sppi[i].IdleTime.LowPart));
+-                        kernel = (float)((HI_T * sppi[i].KernelTime.HighPart) + \
+-                                         (LO_T * sppi[i].KernelTime.LowPart));
+-                        // kernel time includes idle time on windows
+-                        // we return only busy kernel time subtracting
+-                        // idle time from kernel time
+-                        arg = Py_BuildValue("(ddd)", user,
+-                                                     kernel - idle,
+-                                                     idle);
+-                        if (!arg)
+-                            goto error;
+-                        if (PyList_Append(retlist, arg))
+-                            goto error;
+-                        Py_DECREF(arg);
+-                    }
+-                    free(sppi);
+-                    FreeLibrary(hNtDll);
+-                    return retlist;
+-
+-                }  // END NtQuerySystemInformation
+-            }  // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
+-        }  // END GetProcAddress
+-    }  // END LoadLibrary
+-    goto error;
+-
+-error:
+-    Py_XDECREF(arg);
+-    Py_DECREF(retlist);
+-    if (sppi) {
+-        free(sppi);
+-    }
+-    if (hNtDll) {
+-        FreeLibrary(hNtDll);
+-    }
+-    PyErr_SetFromWindowsErr(0);
+-    return NULL;
+-}
+-
+-
+-/*
+- * Return process current working directory as a Python string.
+- */
+-
+-static PyObject*
+-get_process_cwd(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    HANDLE processHandle = NULL;
+-    PVOID pebAddress;
+-    PVOID rtlUserProcParamsAddress;
+-    UNICODE_STRING currentDirectory;
+-    WCHAR *currentDirectoryContent = NULL;
+-    PyObject *returnPyObj = NULL;
+-    PyObject *cwd_from_wchar = NULL;
+-    PyObject *cwd = NULL;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    processHandle = psutil_handle_from_pid(pid);
+-    if (processHandle == NULL) {
+-        return NULL;
+-    }
+-
+-    pebAddress = psutil_get_peb_address(processHandle);
+-
+-    // get the address of ProcessParameters
+-#ifdef _WIN64
+-    if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 32,
+-        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
+-#else
+-    if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10,
+-        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
+-#endif
+-    {
+-        CloseHandle(processHandle);
+-
+-        if (GetLastError() == ERROR_PARTIAL_COPY) {
+-            // this occurs quite often with system processes
+-            return AccessDenied();
+-        }
+-        else {
+-            return PyErr_SetFromWindowsErr(0);
+-        }
+-    }
+-
+-    // Read the currentDirectory UNICODE_STRING structure.
+-    // 0x24 refers to "CurrentDirectoryPath" of RTL_USER_PROCESS_PARAMETERS
+-    // structure, see:
+-    // http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
+-#ifdef _WIN64
+-    if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 56,
+-        &currentDirectory, sizeof(currentDirectory), NULL))
+-#else
+-    if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 0x24,
+-        &currentDirectory, sizeof(currentDirectory), NULL))
+-#endif
+-    {
+-        CloseHandle(processHandle);
+-        if (GetLastError() == ERROR_PARTIAL_COPY) {
+-            // this occurs quite often with system processes
+-            return AccessDenied();
+-        }
+-        else {
+-            return PyErr_SetFromWindowsErr(0);
+-        }
+-    }
+-
+-    // allocate memory to hold cwd
+-    currentDirectoryContent = (WCHAR *)malloc(currentDirectory.Length+1);
+-    if (currentDirectoryContent == NULL) {
+-        PyErr_NoMemory();
+-        goto error;
+-    }
+-
+-
+-    // read cwd
+-    if (!ReadProcessMemory(processHandle, currentDirectory.Buffer,
+-        currentDirectoryContent, currentDirectory.Length, NULL))
+-    {
+-        if (GetLastError() == ERROR_PARTIAL_COPY) {
+-            // this occurs quite often with system processes
+-            AccessDenied();
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-        }
+-        goto error;
+-    }
+-
+-    // null-terminate the string to prevent wcslen from returning
+-    // incorrect length the length specifier is in characters, but
+-    // currentDirectory.Length is in bytes
+-    currentDirectoryContent[(currentDirectory.Length/sizeof(WCHAR))] = '\0';
+-
+-    // convert wchar array to a Python unicode string, and then to UTF8
+-    cwd_from_wchar = PyUnicode_FromWideChar(currentDirectoryContent,
+-                                            wcslen(currentDirectoryContent));
+-    if (cwd_from_wchar == NULL)
+-        goto error;
+-
+-    #if PY_MAJOR_VERSION >= 3
+-        cwd = PyUnicode_FromObject(cwd_from_wchar);
+-    #else
+-        cwd = PyUnicode_AsUTF8String(cwd_from_wchar);
+-    #endif
+-    if (cwd == NULL)
+-        goto error;
+-
+-    // decrement the reference count on our temp unicode str to avoid
+-    // mem leak
+-    returnPyObj = Py_BuildValue("N", cwd);
+-    if (!returnPyObj)
+-        goto error;
+-
+-    Py_DECREF(cwd_from_wchar);
+-
+-    CloseHandle(processHandle);
+-    free(currentDirectoryContent);
+-    return returnPyObj;
+-
+-error:
+-    Py_XDECREF(cwd_from_wchar);
+-    Py_XDECREF(cwd);
+-    Py_XDECREF(returnPyObj);
+-    if (currentDirectoryContent != NULL)
+-        free(currentDirectoryContent);
+-    if (processHandle != NULL)
+-        CloseHandle(processHandle);
+-    return NULL;
+-}
+-
+-
+-/*
+- * Resume or suspends a process
+- */
+-int
+-suspend_resume_process(DWORD pid, int suspend)
+-{
+-    // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx
+-    HANDLE hThreadSnap = NULL;
+-    THREADENTRY32  te32 = {0};
+-
+-    if (pid == 0) {
+-        AccessDenied();
+-        return FALSE;
+-    }
+-
+-    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+-    if (hThreadSnap == INVALID_HANDLE_VALUE) {
+-        PyErr_SetFromWindowsErr(0);
+-        return FALSE;
+-    }
+-
+-    // Fill in the size of the structure before using it
+-    te32.dwSize = sizeof(THREADENTRY32);
+-
+-    if (! Thread32First(hThreadSnap, &te32)) {
+-        PyErr_SetFromWindowsErr(0);
+-        CloseHandle(hThreadSnap);
+-        return FALSE;
+-    }
+-
+-    // Walk the thread snapshot to find all threads of the process.
+-    // If the thread belongs to the process, add its information
+-    // to the display list.
+-    do
+-    {
+-        if (te32.th32OwnerProcessID == pid)
+-        {
+-            HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE,
+-                                        te32.th32ThreadID);
+-            if (hThread == NULL) {
+-                PyErr_SetFromWindowsErr(0);
+-                CloseHandle(hThread);
+-                CloseHandle(hThreadSnap);
+-                return FALSE;
+-            }
+-            if (suspend == 1)
+-            {
+-                if (SuspendThread(hThread) == (DWORD)-1) {
+-                    PyErr_SetFromWindowsErr(0);
+-                    CloseHandle(hThread);
+-                    CloseHandle(hThreadSnap);
+-                    return FALSE;
+-                }
+-            }
+-            else
+-            {
+-                if (ResumeThread(hThread) == (DWORD)-1) {
+-                    PyErr_SetFromWindowsErr(0);
+-                    CloseHandle(hThread);
+-                    CloseHandle(hThreadSnap);
+-                    return FALSE;
+-                }
+-            }
+-            CloseHandle(hThread);
+-        }
+-    } while (Thread32Next(hThreadSnap, &te32));
+-
+-    CloseHandle(hThreadSnap);
+-    return TRUE;
+-}
+-
+-
+-static PyObject*
+-suspend_process(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    int suspend = 1;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    if (! suspend_resume_process(pid, suspend)) {
+-        return NULL;
+-    }
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-
+-
+-static PyObject*
+-resume_process(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    int suspend = 0;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    if (! suspend_resume_process(pid, suspend)) {
+-        return NULL;
+-    }
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-
+-
+-static PyObject*
+-get_process_num_threads(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    int num;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    num = (int)process->NumberOfThreads;
+-    free(buffer);
+-    return Py_BuildValue("i", num);
+-}
+-
+-
+-static PyObject*
+-get_process_threads(PyObject* self, PyObject* args)
+-{
+-    HANDLE hThread;
+-    THREADENTRY32 te32 = {0};
+-    long pid;
+-    int pid_return;
+-    int rc;
+-    FILETIME ftDummy, ftKernel, ftUser;
+-    PyObject* retList = PyList_New(0);
+-    PyObject* pyTuple = NULL;
+-    HANDLE hThreadSnap = NULL;
+-
+-    if (retList == NULL) {
+-        return NULL;
+-    }
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        goto error;
+-    }
+-    if (pid == 0) {
+-        // raise AD instead of returning 0 as procexp is able to
+-        // retrieve useful information somehow
+-        AccessDenied();
+-        goto error;
+-    }
+-
+-    pid_return = psutil_pid_is_running(pid);
+-    if (pid_return == 0) {
+-        NoSuchProcess();
+-        goto error;
+-    }
+-    if (pid_return == -1) {
+-        goto error;
+-    }
+-
+-    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+-    if (hThreadSnap == INVALID_HANDLE_VALUE) {
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    // Fill in the size of the structure before using it
+-    te32.dwSize = sizeof(THREADENTRY32);
+-
+-    if (! Thread32First(hThreadSnap, &te32)) {
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    // Walk the thread snapshot to find all threads of the process.
+-    // If the thread belongs to the process, increase the counter.
+-    do
+-    {
+-        if (te32.th32OwnerProcessID == pid)
+-        {
+-            pyTuple = NULL;
+-            hThread = NULL;
+-            hThread = OpenThread(THREAD_QUERY_INFORMATION,
+-                                  FALSE, te32.th32ThreadID);
+-            if (hThread == NULL) {
+-                // thread has disappeared on us
+-                continue;
+-            }
+-
+-            rc = GetThreadTimes(hThread, &ftDummy, &ftDummy, &ftKernel, &ftUser);
+-            if (rc == 0) {
+-                PyErr_SetFromWindowsErr(0);
+-                goto error;
+-            }
+-
+-            /*
+-            user and kernel times are represented as a FILETIME structure
+-            wich contains a 64-bit value representing the number of
+-            100-nanosecond intervals since January 1, 1601 (UTC).
+-            http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
+-
+-            To convert it into a float representing the seconds that the
+-            process has executed in user/kernel mode I borrowed the code
+-            below from Python's Modules/posixmodule.c
+-            */
+-            pyTuple = Py_BuildValue("kdd",
+-                            te32.th32ThreadID,
+-                            (double)(ftUser.dwHighDateTime*429.4967296 + \
+-                                     ftUser.dwLowDateTime*1e-7),
+-                            (double)(ftKernel.dwHighDateTime*429.4967296 + \
+-                                     ftKernel.dwLowDateTime*1e-7));
+-            if (!pyTuple)
+-                goto error;
+-            if (PyList_Append(retList, pyTuple))
+-                goto error;
+-            Py_DECREF(pyTuple);
+-
+-            CloseHandle(hThread);
+-        }
+-    } while (Thread32Next(hThreadSnap, &te32));
+-
+-    CloseHandle(hThreadSnap);
+-    return retList;
+-
+-error:
+-    Py_XDECREF(pyTuple);
+-    Py_DECREF(retList);
+-    if (hThread != NULL)
+-        CloseHandle(hThread);
+-    if (hThreadSnap != NULL) {
+-        CloseHandle(hThreadSnap);
+-    }
+-    return NULL;
+-}
+-
+-
+-
+-static PyObject*
+-get_process_open_files(PyObject* self, PyObject* args)
+-{
+-    long       pid;
+-    HANDLE     processHandle;
+-    DWORD      access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
+-    PyObject*  filesList;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    processHandle = psutil_handle_from_pid_waccess(pid, access);
+-    if (processHandle == NULL) {
+-        return NULL;
+-    }
+-
+-    filesList = psutil_get_open_files(pid, processHandle);
+-    CloseHandle(processHandle);
+-    if (filesList == NULL) {
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-    return filesList;
+-}
+-
+-
+-/*
+- Accept a filename's drive in native  format like "\Device\HarddiskVolume1\"
+- and return the corresponding drive letter (e.g. "C:\\").
+- If no match is found return an empty string.
+-*/
+-static PyObject*
+-win32_QueryDosDevice(PyObject* self, PyObject* args)
+-{
+-    LPCTSTR   lpDevicePath;
+-    TCHAR d = TEXT('A');
+-    TCHAR     szBuff[5];
+-
+-    if (!PyArg_ParseTuple(args, "s", &lpDevicePath)) {
+-        return NULL;
+-    }
+-
+-    while(d <= TEXT('Z'))
+-    {
+-        TCHAR szDeviceName[3] = {d,TEXT(':'),TEXT('\0')};
+-        TCHAR szTarget[512] = {0};
+-        if (QueryDosDevice(szDeviceName, szTarget, 511) != 0){
+-            //_tprintf (TEXT("%c:\\   =>   %s\n"), d, szTarget);
+-            if(_tcscmp(lpDevicePath, szTarget) == 0) {
+-                _stprintf(szBuff, TEXT("%c:"), d);
+-                return Py_BuildValue("s", szBuff);
+-            }
+-        }
+-        d++;
+-    }
+-    return Py_BuildValue("s", "");
+-}
+-
+-/*
+- * Return process username as a "DOMAIN//USERNAME" string.
+- */
+-static PyObject*
+-get_process_username(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    HANDLE processHandle;
+-    HANDLE tokenHandle;
+-    PTOKEN_USER user;
+-    ULONG bufferSize;
+-    PTSTR name;
+-    ULONG nameSize;
+-    PTSTR domainName;
+-    ULONG domainNameSize;
+-    SID_NAME_USE nameUse;
+-    PTSTR fullName;
+-    PyObject* returnObject;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    processHandle = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
+-    if (processHandle == NULL) {
+-        return NULL;
+-    }
+-
+-    if (!OpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)) {
+-        CloseHandle(processHandle);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    CloseHandle(processHandle);
+-
+-    /* Get the user SID. */
+-
+-    bufferSize = 0x100;
+-    user = malloc(bufferSize);
+-    if (user == NULL) {
+-        return PyErr_NoMemory();
+-    }
+-
+-    if (!GetTokenInformation(tokenHandle,
+-                             TokenUser,
+-                             user,
+-                             bufferSize,
+-                             &bufferSize))
+-    {
+-        free(user);
+-        user = malloc(bufferSize);
+-        if (user == NULL) {
+-            CloseHandle(tokenHandle);
+-            return PyErr_NoMemory();
+-        }
+-        if (!GetTokenInformation(tokenHandle,
+-                                 TokenUser,
+-                                 user,
+-                                 bufferSize,
+-                                 &bufferSize))
+-        {
+-            free(user);
+-            CloseHandle(tokenHandle);
+-            return PyErr_SetFromWindowsErr(0);
+-        }
+-    }
+-
+-    CloseHandle(tokenHandle);
+-
+-    /* Resolve the SID to a name. */
+-
+-    nameSize = 0x100;
+-    domainNameSize = 0x100;
+-
+-    name = malloc(nameSize * sizeof(TCHAR));
+-    if (name == NULL)
+-        return PyErr_NoMemory();
+-    domainName = malloc(domainNameSize * sizeof(TCHAR));
+-    if (domainName == NULL)
+-        return PyErr_NoMemory();
+-
+-    if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
+-                          &domainNameSize, &nameUse))
+-    {
+-        free(name);
+-        free(domainName);
+-        name = malloc(nameSize * sizeof(TCHAR));
+-        if (name == NULL)
+-            return PyErr_NoMemory();
+-        domainName = malloc(domainNameSize * sizeof(TCHAR));
+-        if (domainName == NULL)
+-            return PyErr_NoMemory();
+-        if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
+-                              &domainNameSize, &nameUse))
+-        {
+-            free(name);
+-            free(domainName);
+-            free(user);
+-
+-            return PyErr_SetFromWindowsErr(0);
+-        }
+-    }
+-
+-    nameSize = _tcslen(name);
+-    domainNameSize = _tcslen(domainName);
+-
+-    /* Build the full username string. */
+-    fullName = malloc((domainNameSize + 1 + nameSize + 1) * sizeof(TCHAR));
+-    if (fullName == NULL) {
+-        free(name);
+-        free(domainName);
+-        free(user);
+-        return PyErr_NoMemory();
+-    }
+-    memcpy(fullName, domainName, domainNameSize);
+-    fullName[domainNameSize] = '\\';
+-    memcpy(&fullName[domainNameSize + 1], name, nameSize);
+-    fullName[domainNameSize + 1 + nameSize] = '\0';
+-
+-    returnObject = Py_BuildValue("s", fullName);
+-
+-    free(fullName);
+-    free(name);
+-    free(domainName);
+-    free(user);
+-
+-    return returnObject;
+-}
+-
+-#define BYTESWAP_USHORT(x) ((((USHORT)(x) << 8) | ((USHORT)(x) >> 8)) & 0xffff)
+-
+-#ifndef AF_INET6
+-#define AF_INET6 23
+-#endif
+-
+-static char *state_to_string(ULONG state)
+-{
+-    switch (state)
+-    {
+-    case MIB_TCP_STATE_CLOSED:
+-        return "CLOSE";
+-    case MIB_TCP_STATE_LISTEN:
+-        return "LISTEN";
+-    case MIB_TCP_STATE_SYN_SENT:
+-        return "SYN_SENT";
+-    case MIB_TCP_STATE_SYN_RCVD:
+-        return "SYN_RECV";
+-    case MIB_TCP_STATE_ESTAB:
+-        return "ESTABLISHED";
+-    case MIB_TCP_STATE_FIN_WAIT1:
+-        return "FIN_WAIT1";
+-    case MIB_TCP_STATE_FIN_WAIT2:
+-        return "FIN_WAIT2";
+-    case MIB_TCP_STATE_CLOSE_WAIT:
+-        return "CLOSE_WAIT";
+-    case MIB_TCP_STATE_CLOSING:
+-        return "CLOSING";
+-    case MIB_TCP_STATE_LAST_ACK:
+-        return "LAST_ACK";
+-    case MIB_TCP_STATE_TIME_WAIT:
+-        return "TIME_WAIT";
+-    case MIB_TCP_STATE_DELETE_TCB:
+-        return "DELETE_TCB";
+-    default:
+-        return "";
+-    }
+-}
+-
+-/* mingw support */
+-#ifndef _IPRTRMIB_H
+-typedef struct _MIB_TCP6ROW_OWNER_PID
+-{
+-    UCHAR           ucLocalAddr[16];
+-    DWORD           dwLocalScopeId;
+-    DWORD           dwLocalPort;
+-    UCHAR           ucRemoteAddr[16];
+-    DWORD           dwRemoteScopeId;
+-    DWORD           dwRemotePort;
+-    DWORD           dwState;
+-    DWORD           dwOwningPid;
+-} MIB_TCP6ROW_OWNER_PID, *PMIB_TCP6ROW_OWNER_PID;
+-
+-typedef struct _MIB_TCP6TABLE_OWNER_PID
+-{
+-    DWORD                   dwNumEntries;
+-    MIB_TCP6ROW_OWNER_PID   table[ANY_SIZE];
+-} MIB_TCP6TABLE_OWNER_PID, *PMIB_TCP6TABLE_OWNER_PID;
+-#endif
+-
+-#ifndef __IPHLPAPI_H__
+-typedef struct in6_addr {
+-    union {
+-        UCHAR       Byte[16];
+-        USHORT      Word[8];
+-    } u;
+-} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
+-
+-
+-typedef enum _UDP_TABLE_CLASS {
+-    UDP_TABLE_BASIC,
+-    UDP_TABLE_OWNER_PID,
+-    UDP_TABLE_OWNER_MODULE
+-} UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;
+-
+-
+-typedef struct _MIB_UDPROW_OWNER_PID {
+-    DWORD dwLocalAddr;
+-    DWORD dwLocalPort;
+-    DWORD dwOwningPid;
+-} MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
+-
+-typedef struct _MIB_UDPTABLE_OWNER_PID
+-{
+-    DWORD                   dwNumEntries;
+-    MIB_UDPROW_OWNER_PID    table[ANY_SIZE];
+-} MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;
+-#endif
+-/* end of mingw support */
+-
+-typedef struct _MIB_UDP6ROW_OWNER_PID {
+-    UCHAR           ucLocalAddr[16];
+-    DWORD           dwLocalScopeId;
+-    DWORD           dwLocalPort;
+-    DWORD           dwOwningPid;
+-} MIB_UDP6ROW_OWNER_PID, *PMIB_UDP6ROW_OWNER_PID;
+-
+-typedef struct _MIB_UDP6TABLE_OWNER_PID
+-{
+-    DWORD                   dwNumEntries;
+-    MIB_UDP6ROW_OWNER_PID   table[ANY_SIZE];
+-} MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;
+-
+-
+-#define ConnDecrefPyObjs() Py_DECREF(_AF_INET); \
+-                           Py_DECREF(_AF_INET6);\
+-                           Py_DECREF(_SOCK_STREAM);\
+-                           Py_DECREF(_SOCK_DGRAM);
+-
+-/*
+- * Return a list of network connections opened by a process
+- */
+-static PyObject*
+-get_process_connections(PyObject* self, PyObject* args)
+-{
+-    static long null_address[4] = { 0, 0, 0, 0 };
+-
+-    unsigned long pid;
+-    PyObject* connectionsList;
+-    PyObject* connectionTuple = NULL;
+-    PyObject *af_filter = NULL;
+-    PyObject *type_filter = NULL;
+-
+-    PyObject *_AF_INET = PyLong_FromLong((long)AF_INET);
+-    PyObject *_AF_INET6 = PyLong_FromLong((long)AF_INET6);
+-    PyObject *_SOCK_STREAM = PyLong_FromLong((long)SOCK_STREAM);
+-    PyObject *_SOCK_DGRAM = PyLong_FromLong((long)SOCK_DGRAM);
+-
+-    typedef PSTR (NTAPI *_RtlIpv4AddressToStringA)(struct in_addr *,
+-                                                   PSTR /* __out_ecount(16) */);
+-    _RtlIpv4AddressToStringA rtlIpv4AddressToStringA;
+-    typedef PSTR (NTAPI *_RtlIpv6AddressToStringA)(struct in6_addr *,
+-                                                   PSTR /* __out_ecount(65) */);
+-    _RtlIpv6AddressToStringA rtlIpv6AddressToStringA;
+-    typedef DWORD (WINAPI *_GetExtendedTcpTable)(PVOID, PDWORD, BOOL, ULONG,
+-                                                 TCP_TABLE_CLASS, ULONG);
+-    _GetExtendedTcpTable getExtendedTcpTable;
+-    typedef DWORD (WINAPI *_GetExtendedUdpTable)(PVOID, PDWORD, BOOL, ULONG,
+-                                                 UDP_TABLE_CLASS, ULONG);
+-    _GetExtendedUdpTable getExtendedUdpTable;
+-    PVOID table = NULL;
+-    DWORD tableSize;
+-    PMIB_TCPTABLE_OWNER_PID tcp4Table;
+-    PMIB_UDPTABLE_OWNER_PID udp4Table;
+-    PMIB_TCP6TABLE_OWNER_PID tcp6Table;
+-    PMIB_UDP6TABLE_OWNER_PID udp6Table;
+-    ULONG i;
+-    CHAR addressBufferLocal[65];
+-    PyObject* addressTupleLocal = NULL;
+-    CHAR addressBufferRemote[65];
+-    PyObject* addressTupleRemote = NULL;
+-
+-    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
+-        ConnDecrefPyObjs();
+-        return NULL;
+-    }
+-
+-    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
+-        ConnDecrefPyObjs();
+-        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
+-        return NULL;
+-    }
+-
+-    if (psutil_pid_is_running(pid) == 0) {
+-        ConnDecrefPyObjs();
+-        return NoSuchProcess();
+-    }
+-
+-    /* Import some functions. */
+-    {
+-        HMODULE ntdll;
+-        HMODULE iphlpapi;
+-
+-        ntdll = LoadLibrary(TEXT("ntdll.dll"));
+-        rtlIpv4AddressToStringA = (_RtlIpv4AddressToStringA)GetProcAddress(ntdll,
+-                                                     "RtlIpv4AddressToStringA");
+-        rtlIpv6AddressToStringA = (_RtlIpv6AddressToStringA)GetProcAddress(ntdll,
+-                                                     "RtlIpv6AddressToStringA");
+-        /* TODO: Check these two function pointers */
+-
+-        iphlpapi = LoadLibrary(TEXT("iphlpapi.dll"));
+-        getExtendedTcpTable = (_GetExtendedTcpTable)GetProcAddress(iphlpapi,
+-                                                        "GetExtendedTcpTable");
+-        getExtendedUdpTable = (_GetExtendedUdpTable)GetProcAddress(iphlpapi,
+-                                                        "GetExtendedUdpTable");
+-        FreeLibrary(ntdll);
+-        FreeLibrary(iphlpapi);
+-    }
+-
+-    if ((getExtendedTcpTable == NULL) || (getExtendedUdpTable == NULL)) {
+-        PyErr_SetString(PyExc_NotImplementedError,
+-                        "feature not supported on this Windows version");
+-        ConnDecrefPyObjs();
+-        return NULL;
+-    }
+-
+-    connectionsList = PyList_New(0);
+-    if (connectionsList == NULL) {
+-        ConnDecrefPyObjs();
+-        return NULL;
+-    }
+-
+-    /* TCP IPv4 */
+-
+-    if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
+-        (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
+-    {
+-        table = NULL;
+-        connectionTuple = NULL;
+-        addressTupleLocal = NULL;
+-        addressTupleRemote = NULL;
+-        tableSize = 0;
+-        getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
+-                            TCP_TABLE_OWNER_PID_ALL, 0);
+-
+-        table = malloc(tableSize);
+-        if (table == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
+-                                TCP_TABLE_OWNER_PID_ALL, 0) == 0)
+-        {
+-            tcp4Table = table;
+-
+-            for (i = 0; i < tcp4Table->dwNumEntries; i++)
+-            {
+-                if (tcp4Table->table[i].dwOwningPid != pid) {
+-                    continue;
+-                }
+-
+-                if (tcp4Table->table[i].dwLocalAddr != 0 ||
+-                    tcp4Table->table[i].dwLocalPort != 0)
+-                {
+-                    struct in_addr addr;
+-
+-                    addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
+-                    rtlIpv4AddressToStringA(&addr, addressBufferLocal);
+-                    addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
+-                               BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
+-                }
+-                else
+-                {
+-                    addressTupleLocal = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleLocal == NULL)
+-                    goto error;
+-
+-                // On Windows <= XP, remote addr is filled even if socket
+-                // is in LISTEN mode in which case we just ignore it.
+-                if ((tcp4Table->table[i].dwRemoteAddr != 0 ||
+-                     tcp4Table->table[i].dwRemotePort != 0) &&
+-                    (tcp4Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
+-                {
+-                    struct in_addr addr;
+-
+-                    addr.S_un.S_addr = tcp4Table->table[i].dwRemoteAddr;
+-                    rtlIpv4AddressToStringA(&addr, addressBufferRemote);
+-                    addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
+-                            BYTESWAP_USHORT(tcp4Table->table[i].dwRemotePort));
+-                }
+-                else
+-                {
+-                    addressTupleRemote = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleRemote == NULL)
+-                    goto error;
+-
+-                connectionTuple = Py_BuildValue("(iiiNNs)",
+-                    -1,
+-                    AF_INET,
+-                    SOCK_STREAM,
+-                    addressTupleLocal,
+-                    addressTupleRemote,
+-                    state_to_string(tcp4Table->table[i].dwState)
+-                    );
+-                if (!connectionTuple)
+-                    goto error;
+-                if (PyList_Append(connectionsList, connectionTuple))
+-                    goto error;
+-                Py_DECREF(connectionTuple);
+-            }
+-        }
+-
+-        free(table);
+-    }
+-
+-    /* TCP IPv6 */
+-
+-    if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
+-        (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
+-    {
+-        table = NULL;
+-        connectionTuple = NULL;
+-        addressTupleLocal = NULL;
+-        addressTupleRemote = NULL;
+-        tableSize = 0;
+-        getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
+-                            TCP_TABLE_OWNER_PID_ALL, 0);
+-
+-        table = malloc(tableSize);
+-        if (table == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
+-                                 TCP_TABLE_OWNER_PID_ALL, 0) == 0)
+-        {
+-            tcp6Table = table;
+-
+-            for (i = 0; i < tcp6Table->dwNumEntries; i++)
+-            {
+-                if (tcp6Table->table[i].dwOwningPid != pid) {
+-                    continue;
+-                }
+-
+-                if (memcmp(tcp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
+-                tcp6Table->table[i].dwLocalPort != 0)
+-                {
+-                    struct in6_addr addr;
+-
+-                    memcpy(&addr, tcp6Table->table[i].ucLocalAddr, 16);
+-                    rtlIpv6AddressToStringA(&addr, addressBufferLocal);
+-                    addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
+-                             BYTESWAP_USHORT(tcp6Table->table[i].dwLocalPort));
+-                }
+-                else
+-                {
+-                    addressTupleLocal = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleLocal == NULL)
+-                    goto error;
+-
+-                // On Windows <= XP, remote addr is filled even if socket
+-                // is in LISTEN mode in which case we just ignore it.
+-                if ((memcmp(tcp6Table->table[i].ucRemoteAddr, null_address, 16) != 0 ||
+-                    tcp6Table->table[i].dwRemotePort != 0) &&
+-                   (tcp6Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
+-                {
+-                    struct in6_addr addr;
+-
+-                    memcpy(&addr, tcp6Table->table[i].ucRemoteAddr, 16);
+-                    rtlIpv6AddressToStringA(&addr, addressBufferRemote);
+-                    addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
+-                            BYTESWAP_USHORT(tcp6Table->table[i].dwRemotePort));
+-                }
+-                else
+-                {
+-                    addressTupleRemote = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleRemote == NULL)
+-                    goto error;
+-
+-                connectionTuple = Py_BuildValue("(iiiNNs)",
+-                    -1,
+-                    AF_INET6,
+-                    SOCK_STREAM,
+-                    addressTupleLocal,
+-                    addressTupleRemote,
+-                    state_to_string(tcp6Table->table[i].dwState)
+-                    );
+-                if (!connectionTuple)
+-                    goto error;
+-                if (PyList_Append(connectionsList, connectionTuple))
+-                    goto error;
+-                Py_DECREF(connectionTuple);
+-            }
+-        }
+-
+-        free(table);
+-    }
+-
+-    /* UDP IPv4 */
+-
+-    if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
+-        (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
+-    {
+-        table = NULL;
+-        connectionTuple = NULL;
+-        addressTupleLocal = NULL;
+-        addressTupleRemote = NULL;
+-        tableSize = 0;
+-        getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
+-                            UDP_TABLE_OWNER_PID, 0);
+-
+-        table = malloc(tableSize);
+-        if (table == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
+-                                 UDP_TABLE_OWNER_PID, 0) == 0)
+-        {
+-            udp4Table = table;
+-
+-            for (i = 0; i < udp4Table->dwNumEntries; i++)
+-            {
+-                if (udp4Table->table[i].dwOwningPid != pid) {
+-                    continue;
+-                }
+-
+-                if (udp4Table->table[i].dwLocalAddr != 0 ||
+-                    udp4Table->table[i].dwLocalPort != 0)
+-                {
+-                    struct in_addr addr;
+-
+-                    addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
+-                    rtlIpv4AddressToStringA(&addr, addressBufferLocal);
+-                    addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
+-                                BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
+-                }
+-                else
+-                {
+-                    addressTupleLocal = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleLocal == NULL)
+-                    goto error;
+-
+-                connectionTuple = Py_BuildValue("(iiiNNs)",
+-                    -1,
+-                    AF_INET,
+-                    SOCK_DGRAM,
+-                    addressTupleLocal,
+-                    PyTuple_New(0),
+-                    ""
+-                    );
+-                if (!connectionTuple)
+-                    goto error;
+-                if (PyList_Append(connectionsList, connectionTuple))
+-                    goto error;
+-                Py_DECREF(connectionTuple);
+-            }
+-        }
+-
+-        free(table);
+-    }
+-
+-    /* UDP IPv6 */
+-
+-    if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
+-        (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
+-    {
+-        table = NULL;
+-        connectionTuple = NULL;
+-        addressTupleLocal = NULL;
+-        addressTupleRemote = NULL;
+-        tableSize = 0;
+-        getExtendedUdpTable(NULL, &tableSize, FALSE,
+-                            AF_INET6, UDP_TABLE_OWNER_PID, 0);
+-
+-        table = malloc(tableSize);
+-        if (table == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6,
+-                                 UDP_TABLE_OWNER_PID, 0) == 0)
+-        {
+-            udp6Table = table;
+-
+-            for (i = 0; i < udp6Table->dwNumEntries; i++)
+-            {
+-                if (udp6Table->table[i].dwOwningPid != pid) {
+-                    continue;
+-                }
+-
+-                if (memcmp(udp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
+-                    udp6Table->table[i].dwLocalPort != 0)
+-                {
+-                    struct in6_addr addr;
+-
+-                    memcpy(&addr, udp6Table->table[i].ucLocalAddr, 16);
+-                    rtlIpv6AddressToStringA(&addr, addressBufferLocal);
+-                    addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
+-                              BYTESWAP_USHORT(udp6Table->table[i].dwLocalPort));
+-                }
+-                else
+-                {
+-                    addressTupleLocal = PyTuple_New(0);
+-                }
+-
+-                if (addressTupleLocal == NULL)
+-                    goto error;
+-
+-                connectionTuple = Py_BuildValue("(iiiNNs)",
+-                    -1,
+-                    AF_INET6,
+-                    SOCK_DGRAM,
+-                    addressTupleLocal,
+-                    PyTuple_New(0),
+-                    ""
+-                    );
+-                if (!connectionTuple)
+-                    goto error;
+-                if (PyList_Append(connectionsList, connectionTuple))
+-                    goto error;
+-                Py_DECREF(connectionTuple);
+-            }
+-        }
+-
+-        free(table);
+-    }
+-
+-    ConnDecrefPyObjs();
+-    return connectionsList;
+-
+-error:
+-    ConnDecrefPyObjs();
+-    Py_XDECREF(connectionTuple);
+-    Py_XDECREF(addressTupleLocal);
+-    Py_XDECREF(addressTupleRemote);
+-    Py_DECREF(connectionsList);
+-    if (table != NULL)
+-        free(table);
+-    return NULL;
+-}
+-
+-
+-/*
+- * Get process priority as a Python integer.
+- */
+-static PyObject*
+-get_process_priority(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    DWORD priority;
+-    HANDLE hProcess;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    priority = GetPriorityClass(hProcess);
+-    CloseHandle(hProcess);
+-    if (priority == 0) {
+-        PyErr_SetFromWindowsErr(0);
+-        return NULL;
+-    }
+-    return Py_BuildValue("i", priority);
+-}
+-
+-
+-/*
+- * Set process priority.
+- */
+-static PyObject*
+-set_process_priority(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    int priority;
+-    int retval;
+-    HANDLE hProcess;
+-    DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
+-    if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
+-        return NULL;
+-    }
+-
+-    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    retval = SetPriorityClass(hProcess, priority);
+-    CloseHandle(hProcess);
+-    if (retval == 0) {
+-        PyErr_SetFromWindowsErr(0);
+-        return NULL;
+-    }
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-
+-
+-#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+-/*
+- * Get process IO priority as a Python integer.
+- */
+-static PyObject*
+-get_process_io_priority(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    HANDLE hProcess;
+-    PULONG IoPriority;
+-
+-    _NtQueryInformationProcess NtQueryInformationProcess =
+-        (_NtQueryInformationProcess)GetProcAddress(
+-        GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    NtQueryInformationProcess(
+-        hProcess,
+-        ProcessIoPriority,
+-        &IoPriority,
+-        sizeof(ULONG),
+-        NULL
+-    );
+-    CloseHandle(hProcess);
+-    return Py_BuildValue("i", IoPriority);
+-}
+-
+-
+-/*
+- * Set process IO priority.
+- */
+-static PyObject*
+-set_process_io_priority(PyObject* self, PyObject* args)
+-{
+-    long pid;
+-    int prio;
+-    HANDLE hProcess;
+-
+-    _NtSetInformationProcess NtSetInformationProcess =
+-        (_NtSetInformationProcess)GetProcAddress(
+-        GetModuleHandleA("ntdll.dll"), "NtSetInformationProcess");
+-
+-    if (NtSetInformationProcess == NULL) {
+-        PyErr_SetString(PyExc_RuntimeError,
+-                        "couldn't get NtSetInformationProcess");
+-        return NULL;
+-    }
+-
+-    if (! PyArg_ParseTuple(args, "li", &pid, &prio)) {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_ALL_ACCESS);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    NtSetInformationProcess(
+-        hProcess,
+-        ProcessIoPriority,
+-        (PVOID)&prio,
+-        sizeof((PVOID)prio)
+-    );
+-
+-    CloseHandle(hProcess);
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-#endif
+-
+-
+-/*
+- * Return a Python tuple referencing process I/O counters.
+- */
+-static PyObject*
+-get_process_io_counters(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    HANDLE hProcess;
+-    IO_COUNTERS IoCounters;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (NULL == hProcess) {
+-        return NULL;
+-    }
+-    if (! GetProcessIoCounters(hProcess, &IoCounters)) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-    CloseHandle(hProcess);
+-    return Py_BuildValue("(KKKK)", IoCounters.ReadOperationCount,
+-                                   IoCounters.WriteOperationCount,
+-                                   IoCounters.ReadTransferCount,
+-                                   IoCounters.WriteTransferCount);
+-}
+-
+-
+-/*
+- * Alternative implementation of the one above but bypasses ACCESS DENIED.
+- */
+-static PyObject*
+-get_process_io_counters_2(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    LONGLONG rcount, wcount, rbytes, wbytes;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    rcount = process->ReadOperationCount.QuadPart;
+-    wcount = process->WriteOperationCount.QuadPart;
+-    rbytes = process->ReadTransferCount.QuadPart;
+-    wbytes = process->WriteTransferCount.QuadPart;
+-    free(buffer);
+-    return Py_BuildValue("KKKK", rcount, wcount, rbytes, wbytes);
+-}
+-
+-
+-/*
+- * Return process CPU affinity as a bitmask
+- */
+-static PyObject*
+-get_process_cpu_affinity(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    HANDLE hProcess;
+-    PDWORD_PTR proc_mask;
+-    PDWORD_PTR system_mask;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-    if (GetProcessAffinityMask(hProcess, &proc_mask, &system_mask) == 0) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    CloseHandle(hProcess);
+-#ifdef _WIN64
+-    return Py_BuildValue("K", (unsigned long long)proc_mask);
+-#else
+-    return Py_BuildValue("k", (unsigned long)proc_mask);
+-#endif
+-}
+-
+-
+-/*
+- * Set process CPU affinity
+- */
+-static PyObject*
+-set_process_cpu_affinity(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    HANDLE hProcess;
+-    DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
+-    DWORD_PTR mask;
+-
+-#ifdef _WIN64
+-    if (! PyArg_ParseTuple(args, "lK", &pid, &mask))
+-#else
+-    if (! PyArg_ParseTuple(args, "lk", &pid, &mask))
+-#endif
+-    {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
+-    if (hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    if (SetProcessAffinityMask(hProcess, mask) == 0) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    CloseHandle(hProcess);
+-    Py_INCREF(Py_None);
+-    return Py_None;
+-}
+-
+-
+-/*
+- * Return True if one of the process threads is in a waiting or
+- * suspended status.
+- */
+-static PyObject*
+-is_process_suspended(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    ULONG i;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    for (i = 0; i < process->NumberOfThreads; i++) {
+-        if (process->Threads[i].ThreadState != Waiting ||
+-            process->Threads[i].WaitReason != Suspended)
+-        {
+-            free(buffer);
+-            Py_RETURN_FALSE;
+-        }
+-    }
+-    free(buffer);
+-    Py_RETURN_TRUE;
+-}
+-
+-
+-/*
+- * Return path's disk total and free as a Python tuple.
+- */
+-static PyObject*
+-get_disk_usage(PyObject* self, PyObject* args)
+-{
+-    BOOL retval;
+-    ULARGE_INTEGER _, total, free;
+-    LPCTSTR path;
+-
+-    if (! PyArg_ParseTuple(args, "s", &path)) {
+-        return NULL;
+-    }
+-
+-    Py_BEGIN_ALLOW_THREADS
+-    retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
+-    Py_END_ALLOW_THREADS
+-    if (retval == 0) {
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
+-}
+-
+-
+-/*
+- * Return a Python list of named tuples with overall network I/O information
+- */
+-static PyObject*
+-get_network_io_counters(PyObject* self, PyObject* args)
+-{
+-    int attempts = 0;
+-    int outBufLen = 15000;
+-    DWORD dwRetVal = 0;
+-    MIB_IFROW *pIfRow = NULL;
+-    ULONG flags = 0;
+-    ULONG family = AF_UNSPEC;
+-    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
+-    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
+-
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_nic_info = NULL;
+-    PyObject* py_pre_nic_name = NULL;
+-    PyObject* py_nic_name = NULL;
+-
+-    if (py_retdict == NULL) {
+-        return NULL;
+-    }
+-    do {
+-        pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
+-        if (pAddresses == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses,
+-                                        &outBufLen);
+-        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
+-            free(pAddresses);
+-            pAddresses = NULL;
+-        }
+-        else {
+-            break;
+-        }
+-
+-        attempts++;
+-    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (attempts < 3));
+-
+-    if (dwRetVal != NO_ERROR) {
+-        PyErr_SetString(PyExc_RuntimeError,  "GetAdaptersAddresses() failed.");
+-        goto error;
+-    }
+-
+-    pCurrAddresses = pAddresses;
+-    while (pCurrAddresses) {
+-        py_pre_nic_name = NULL;
+-        py_nic_name = NULL;
+-        py_nic_info = NULL;
+-        pIfRow = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
+-
+-        if (pIfRow == NULL) {
+-            PyErr_NoMemory();
+-            goto error;
+-        }
+-
+-        pIfRow->dwIndex = pCurrAddresses->IfIndex;
+-        dwRetVal = GetIfEntry(pIfRow);
+-        if (dwRetVal != NO_ERROR) {
+-            PyErr_SetString(PyExc_RuntimeError, "GetIfEntry() failed.");
+-            goto error;
+-        }
+-
+-        py_nic_info = Py_BuildValue("(IIIIIIII)",
+-                                    pIfRow->dwOutOctets,
+-                                    pIfRow->dwInOctets,
+-                                    pIfRow->dwOutUcastPkts,
+-                                    pIfRow->dwInUcastPkts,
+-                                    pIfRow->dwInErrors,
+-                                    pIfRow->dwOutErrors,
+-                                    pIfRow->dwInDiscards,
+-                                    pIfRow->dwOutDiscards);
+-        if (!py_nic_info)
+-            goto error;
+-
+-        py_pre_nic_name = PyUnicode_FromWideChar(
+-                                pCurrAddresses->FriendlyName,
+-                                wcslen(pCurrAddresses->FriendlyName));
+-        if (py_pre_nic_name == NULL)
+-            goto error;
+-        py_nic_name = PyUnicode_FromObject(py_pre_nic_name);
+-        if (py_nic_name == NULL)
+-            goto error;
+-        if (PyDict_SetItem(py_retdict, py_nic_name, py_nic_info))
+-            goto error;
+-        Py_XDECREF(py_pre_nic_name);
+-        Py_XDECREF(py_nic_name);
+-        Py_XDECREF(py_nic_info);
+-
+-        free(pIfRow);
+-        pCurrAddresses = pCurrAddresses->Next;
+-    }
+-
+-    free(pAddresses);
+-    return py_retdict;
+-
+-error:
+-    Py_XDECREF(py_pre_nic_name);
+-    Py_XDECREF(py_nic_name);
+-    Py_XDECREF(py_nic_info);
+-    Py_DECREF(py_retdict);
+-    if (pAddresses != NULL)
+-        free(pAddresses);
+-    if (pIfRow != NULL)
+-        free(pIfRow);
+-    return NULL;
+-}
+-
+-// fix for mingw32, see
+-// https://code.google.com/p/psutil/issues/detail?id=351#c2
+-typedef struct _DISK_PERFORMANCE_WIN_2008 {
+-       LARGE_INTEGER BytesRead;
+-       LARGE_INTEGER BytesWritten;
+-       LARGE_INTEGER ReadTime;
+-       LARGE_INTEGER WriteTime;
+-       LARGE_INTEGER IdleTime;
+-       DWORD         ReadCount;
+-       DWORD         WriteCount;
+-       DWORD         QueueDepth;
+-       DWORD         SplitCount;
+-       LARGE_INTEGER QueryTime;
+-       DWORD         StorageDeviceNumber;
+-       WCHAR         StorageManagerName[8];
+-} DISK_PERFORMANCE_WIN_2008;
+-
+-/*
+- * Return a Python dict of tuples for disk I/O information
+- */
+-static PyObject*
+-get_disk_io_counters(PyObject* self, PyObject* args)
+-{
+-    DISK_PERFORMANCE_WIN_2008 diskPerformance;
+-    DWORD dwSize;
+-    HANDLE hDevice = NULL;
+-    char szDevice[MAX_PATH];
+-    char szDeviceDisplay[MAX_PATH];
+-    int devNum;
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_disk_info = NULL;
+-    if (py_retdict == NULL) {
+-        return NULL;
+-    }
+-
+-    // Apparently there's no way to figure out how many times we have
+-    // to iterate in order to find valid drives.
+-    // Let's assume 32, which is higher than 26, the number of letters
+-    // in the alphabet (from A:\ to Z:\).
+-    for (devNum=0; devNum <= 32; ++devNum) {
+-        py_disk_info = NULL;
+-        sprintf(szDevice, "\\\\.\\PhysicalDrive%d", devNum);
+-        hDevice = CreateFile(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
+-                             NULL, OPEN_EXISTING, 0, NULL);
+-
+-        if (hDevice == INVALID_HANDLE_VALUE) {
+-            continue;
+-        }
+-        if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
+-                            &diskPerformance, sizeof(diskPerformance),
+-                            &dwSize, NULL))
+-        {
+-            sprintf(szDeviceDisplay, "PhysicalDrive%d", devNum);
+-            py_disk_info = Py_BuildValue("(IILLLL)",
+-                                         diskPerformance.ReadCount,
+-                                         diskPerformance.WriteCount,
+-                                         diskPerformance.BytesRead,
+-                                         diskPerformance.BytesWritten,
+-                                         (diskPerformance.ReadTime.QuadPart
+-                                            * 10) / 1000,
+-                                         (diskPerformance.WriteTime.QuadPart
+-                                            * 10) / 1000);
+-            if (!py_disk_info)
+-                goto error;
+-            if (PyDict_SetItemString(py_retdict, szDeviceDisplay, py_disk_info))
+-                goto error;
+-            Py_XDECREF(py_disk_info);
+-        }
+-        else {
+-            // XXX we might get here with ERROR_INSUFFICIENT_BUFFER when
+-            // compiling with mingw32; not sure what to do.
+-            //return PyErr_SetFromWindowsErr(0);
+-            ;;
+-        }
+-
+-        CloseHandle(hDevice);
+-    }
+-
+-    return py_retdict;
+-
+-error:
+-    Py_XDECREF(py_disk_info);
+-    Py_DECREF(py_retdict);
+-    if (hDevice != NULL)
+-        CloseHandle(hDevice);
+-    return NULL;
+-}
+-
+-
+-static char *get_drive_type(int type)
+-{
+-    switch (type) {
+-        case DRIVE_FIXED:
+-            return "fixed";
+-        case DRIVE_CDROM:
+-            return "cdrom";
+-        case DRIVE_REMOVABLE:
+-            return "removable";
+-        case DRIVE_UNKNOWN:
+-            return "unknown";
+-        case DRIVE_NO_ROOT_DIR:
+-            return "unmounted";
+-        case DRIVE_REMOTE:
+-            return "remote";
+-        case DRIVE_RAMDISK:
+-            return "ramdisk";
+-        default:
+-            return "?";
+-    }
+-}
+-
+-
+-#define _ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+-
+-/*
+- * Return disk partitions as a list of tuples such as
+- * (drive_letter, drive_letter, type, "")
+- */
+-static PyObject*
+-get_disk_partitions(PyObject* self, PyObject* args)
+-{
+-    DWORD num_bytes;
+-    char drive_strings[255];
+-    char* drive_letter = drive_strings;
+-    int all;
+-    int type;
+-    int ret;
+-    char opts[20];
+-    LPTSTR fs_type[MAX_PATH + 1] = { 0 };
+-    DWORD pflags = 0;
+-    PyObject* py_all;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_tuple = NULL;
+-
+-    if (py_retlist == NULL) {
+-        return NULL;
+-    }
+-
+-    // avoid to visualize a message box in case something goes wrong
+-    // see http://code.google.com/p/psutil/issues/detail?id=264
+-    SetErrorMode(SEM_FAILCRITICALERRORS);
+-
+-    if (! PyArg_ParseTuple(args, "O", &py_all)) {
+-        goto error;
+-    }
+-    all = PyObject_IsTrue(py_all);
+-
+-    Py_BEGIN_ALLOW_THREADS
+-    num_bytes = GetLogicalDriveStrings(254, drive_letter);
+-    Py_END_ALLOW_THREADS
+-
+-    if (num_bytes == 0) {
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    while (*drive_letter != 0) {
+-        py_tuple = NULL;
+-        opts[0] = 0;
+-        fs_type[0] = 0;
+-
+-        Py_BEGIN_ALLOW_THREADS
+-        type = GetDriveType(drive_letter);
+-        Py_END_ALLOW_THREADS
+-
+-        // by default we only show hard drives and cd-roms
+-        if (all == 0) {
+-            if ((type == DRIVE_UNKNOWN) ||
+-                (type == DRIVE_NO_ROOT_DIR) ||
+-                (type == DRIVE_REMOTE) ||
+-                (type == DRIVE_RAMDISK)) {
+-                goto next;
+-            }
+-            // floppy disk: skip it by default as it introduces a
+-            // considerable slowdown.
+-            if ((type == DRIVE_REMOVABLE) && (strcmp(drive_letter, "A:\\") == 0)) {
+-                goto next;
+-            }
+-        }
+-
+-        ret = GetVolumeInformation(drive_letter, NULL, _ARRAYSIZE(drive_letter),
+-                                   NULL, NULL, &pflags, fs_type,
+-                                   _ARRAYSIZE(fs_type));
+-        if (ret == 0) {
+-            // We might get here in case of a floppy hard drive, in
+-            // which case the error is (21, "device not ready").
+-            // Let's pretend it didn't happen as we already have
+-            // the drive name and type ('removable').
+-            strcat(opts, "");
+-            SetLastError(0);
+-        }
+-        else {
+-            if (pflags & FILE_READ_ONLY_VOLUME) {
+-                strcat(opts, "ro");
+-            }
+-            else {
+-                strcat(opts, "rw");
+-            }
+-            if (pflags & FILE_VOLUME_IS_COMPRESSED) {
+-                strcat(opts, ",compressed");
+-            }
+-        }
+-
+-        if (strlen(opts) > 0) {
+-            strcat(opts, ",");
+-        }
+-        strcat(opts, get_drive_type(type));
+-
+-        py_tuple = Py_BuildValue("(ssss)",
+-            drive_letter,
+-            drive_letter,
+-            fs_type,  // either FAT, FAT32, NTFS, HPFS, CDFS, UDF or NWFS
+-            opts);
+-        if (!py_tuple)
+-            goto error;
+-        if (PyList_Append(py_retlist, py_tuple))
+-            goto error;
+-        Py_DECREF(py_tuple);
+-        goto next;
+-
+-        next:
+-            drive_letter = strchr(drive_letter, 0) + 1;
+-    }
+-
+-    SetErrorMode(0);
+-    return py_retlist;
+-
+-error:
+-    SetErrorMode(0);
+-    Py_XDECREF(py_tuple);
+-    Py_DECREF(py_retlist);
+-    return NULL;
+-}
+-
+-
+-#ifdef UNICODE
+-#define WTSOpenServer WTSOpenServerW
+-#else
+-#define WTSOpenServer WTSOpenServerA
+-#endif
+-
+-
+-/*
+- * Return a Python dict of tuples for disk I/O information
+- */
+-static PyObject*
+-get_system_users(PyObject* self, PyObject* args)
+-{
+-    HANDLE hServer = NULL;
+-    LPTSTR buffer_user = NULL;
+-    LPTSTR buffer_addr = NULL;
+-    PWTS_SESSION_INFO sessions = NULL;
+-    DWORD count;
+-    DWORD i;
+-    DWORD sessionId;
+-    DWORD bytes;
+-    PWTS_CLIENT_ADDRESS address;
+-    char address_str[50];
+-    long long unix_time;
+-
+-    PWINSTATIONQUERYINFORMATIONW WinStationQueryInformationW;
+-    WINSTATION_INFO station_info;
+-    HINSTANCE hInstWinSta = NULL;
+-    ULONG returnLen;
+-
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_tuple = NULL;
+-    PyObject* py_address = NULL;
+-    if (py_retlist == NULL) {
+-        return NULL;
+-    }
+-
+-    hInstWinSta = LoadLibraryA("winsta.dll");
+-    WinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW)
+-        GetProcAddress(hInstWinSta, "WinStationQueryInformationW");
+-
+-    hServer = WTSOpenServer('\0');
+-    if (hServer == NULL) {
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    if (WTSEnumerateSessions(hServer, 0, 1, &sessions, &count) == 0) {
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    for (i=0; i<count; i++) {
+-        py_address = NULL;
+-        py_tuple = NULL;
+-        sessionId = sessions[i].SessionId;
+-        if (buffer_user != NULL) {
+-            WTSFreeMemory(buffer_user);
+-        }
+-        if (buffer_addr != NULL) {
+-            WTSFreeMemory(buffer_addr);
+-        }
+-
+-        buffer_user = NULL;
+-        buffer_addr = NULL;
+-
+-        // username
+-        bytes = 0;
+-        if (WTSQuerySessionInformation(hServer, sessionId, WTSUserName,
+-                                        &buffer_user, &bytes) == 0) {
+-            PyErr_SetFromWindowsErr(0);
+-            goto error;
+-        }
+-        if (bytes == 1) {
+-            continue;
+-        }
+-
+-        // address
+-        bytes = 0;
+-        if (WTSQuerySessionInformation(hServer, sessionId, WTSClientAddress,
+-                                       &buffer_addr, &bytes) == 0) {
+-            PyErr_SetFromWindowsErr(0);
+-            goto error;
+-        }
+-
+-        address = (PWTS_CLIENT_ADDRESS)buffer_addr;
+-        if (address->AddressFamily == 0) {  // AF_INET
+-            sprintf(address_str, "%u.%u.%u.%u", address->Address[0],
+-                                                address->Address[1],
+-                                                address->Address[2],
+-                                                address->Address[3]);
+-            py_address = Py_BuildValue("s", address_str);
+-            if (!py_address)
+-                goto error;
+-        }
+-        else {
+-            py_address = Py_None;
+-        }
+-
+-        // login time
+-        if (!WinStationQueryInformationW(hServer,
+-                                         sessionId,
+-                                         WinStationInformation,
+-                                         &station_info,
+-                                         sizeof(station_info),
+-                                         &returnLen))
+-                                         {
+-            goto error;
+-        }
+-
+-        unix_time = ((LONGLONG)station_info.ConnectTime.dwHighDateTime) << 32;
+-        unix_time += station_info.ConnectTime.dwLowDateTime - 116444736000000000LL;
+-        unix_time /= 10000000;
+-
+-        py_tuple = Py_BuildValue("sOd", buffer_user,
+-                                        py_address,
+-                                        (double)unix_time);
+-        if (!py_tuple)
+-            goto error;
+-        if (PyList_Append(py_retlist, py_tuple))
+-            goto error;
+-        Py_XDECREF(py_address);
+-        Py_XDECREF(py_tuple);
+-    }
+-
+-    WTSCloseServer(hServer);
+-    WTSFreeMemory(sessions);
+-    WTSFreeMemory(buffer_user);
+-    WTSFreeMemory(buffer_addr);
+-    FreeLibrary(hInstWinSta);
+-    return py_retlist;
+-
+-error:
+-    Py_XDECREF(py_tuple);
+-    Py_XDECREF(py_address);
+-    Py_DECREF(py_retlist);
+-
+-    if (hInstWinSta != NULL) {
+-        FreeLibrary(hInstWinSta);
+-    }
+-    if (hServer != NULL) {
+-        WTSCloseServer(hServer);
+-    }
+-    if (sessions != NULL) {
+-        WTSFreeMemory(sessions);
+-    }
+-    if (buffer_user != NULL) {
+-        WTSFreeMemory(buffer_user);
+-    }
+-    if (buffer_addr != NULL) {
+-        WTSFreeMemory(buffer_addr);
+-    }
+-    return NULL;
+-}
+-
+-
+-/*
+- * Return the number of handles opened by process.
+- */
+-static PyObject*
+-get_process_num_handles(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    HANDLE hProcess;
+-    DWORD handleCount;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (NULL == hProcess) {
+-        return NULL;
+-    }
+-    if (! GetProcessHandleCount(hProcess, &handleCount)) {
+-        CloseHandle(hProcess);
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-    CloseHandle(hProcess);
+-    return Py_BuildValue("k", handleCount);
+-}
+-
+-
+-/*
+- * Alternative implementation of the one above but bypasses ACCESS DENIED.
+- */
+-static PyObject*
+-get_process_num_handles_2(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    ULONG count;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    count = process->HandleCount;
+-    free(buffer);
+-    return Py_BuildValue("k", count);
+-}
+-
+-
+-/*
+- * Return the number of context switches executed by process.
+- */
+-static PyObject*
+-get_process_num_ctx_switches(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-    PVOID buffer;
+-    ULONG i;
+-    ULONG total = 0;
+-
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        return NULL;
+-    }
+-    if (! get_process_info(pid, &process, &buffer)) {
+-        return NULL;
+-    }
+-    for (i=0; i < process->NumberOfThreads; i++) {
+-        total += process->Threads[i].ContextSwitches;
+-    }
+-    free(buffer);
+-    return Py_BuildValue("ki", total, 0);
+-}
+-
+-
+-static char *get_region_protection_string(ULONG protection)
+-{
+-    switch (protection & 0xff) {
+-        case PAGE_NOACCESS:
+-            return "";
+-        case PAGE_READONLY:
+-            return "r";
+-        case PAGE_READWRITE:
+-            return "rw";
+-        case PAGE_WRITECOPY:
+-            return "wc";
+-        case PAGE_EXECUTE:
+-            return "x";
+-        case PAGE_EXECUTE_READ:
+-            return "xr";
+-        case PAGE_EXECUTE_READWRITE:
+-            return "xrw";
+-        case PAGE_EXECUTE_WRITECOPY:
+-            return "xwc";
+-        default:
+-            return "?";
+-    }
+-}
+-
+-/*
+- * Return a list of process's memory mappings.
+- */
+-static PyObject*
+-get_process_memory_maps(PyObject* self, PyObject* args)
+-{
+-    DWORD pid;
+-    HANDLE hProcess = NULL;
+-    MEMORY_BASIC_INFORMATION basicInfo;
+-    PVOID baseAddress;
+-    PVOID previousAllocationBase;
+-    CHAR mappedFileName[MAX_PATH];
+-    SYSTEM_INFO system_info;
+-    LPVOID maxAddr;
+-    PyObject* py_list = PyList_New(0);
+-    PyObject* py_tuple = NULL;
+-
+-    if (py_list == NULL) {
+-        return NULL;
+-    }
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+-        goto error;
+-    }
+-    hProcess = psutil_handle_from_pid(pid);
+-    if (NULL == hProcess) {
+-        goto error;
+-    }
+-
+-    GetSystemInfo(&system_info);
+-    maxAddr = system_info.lpMaximumApplicationAddress;
+-    baseAddress = NULL;
+-    previousAllocationBase = NULL;
+-
+-    while (VirtualQueryEx(hProcess, baseAddress, &basicInfo,
+-                          sizeof(MEMORY_BASIC_INFORMATION)))
+-    {
+-        py_tuple = NULL;
+-        if (baseAddress > maxAddr) {
+-            break;
+-        }
+-        if (GetMappedFileNameA(hProcess, baseAddress, mappedFileName,
+-                               sizeof(mappedFileName)))
+-        {
+-            py_tuple = Py_BuildValue("(kssI)",
+-                (unsigned long)baseAddress,
+-                get_region_protection_string(basicInfo.Protect),
+-                mappedFileName,
+-                basicInfo.RegionSize
+-            );
+-            if (!py_tuple)
+-                goto error;
+-            if (PyList_Append(py_list, py_tuple))
+-                goto error;
+-            Py_DECREF(py_tuple);
+-        }
+-        previousAllocationBase = basicInfo.AllocationBase;
+-        baseAddress = (PCHAR)baseAddress + basicInfo.RegionSize;
+-    }
+-
+-    CloseHandle(hProcess);
+-    return py_list;
+-
+-error:
+-    Py_XDECREF(py_tuple);
+-    Py_DECREF(py_list);
+-    if (hProcess != NULL)
+-        CloseHandle(hProcess);
+-    return NULL;
+-}
+-
+-// ------------------------ Python init ---------------------------
+-
+-static PyMethodDef
+-PsutilMethods[] =
+-{
+-    // --- per-process functions
+-
+-    {"get_process_name", get_process_name, METH_VARARGS,
+-        "Return process name"},
+-    {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
+-        "Return process cmdline as a list of cmdline arguments"},
+-    {"get_process_exe", get_process_exe, METH_VARARGS,
+-        "Return path of the process executable"},
+-    {"get_process_ppid", get_process_ppid, METH_VARARGS,
+-        "Return process ppid as an integer"},
+-    {"kill_process", kill_process, METH_VARARGS,
+-        "Kill the process identified by the given PID"},
+-    {"get_process_cpu_times", get_process_cpu_times, METH_VARARGS,
+-        "Return tuple of user/kern time for the given PID"},
+-    {"get_process_create_time", get_process_create_time, METH_VARARGS,
+-        "Return a float indicating the process create time expressed in "
+-        "seconds since the epoch"},
+-    {"get_process_memory_info", get_process_memory_info, METH_VARARGS,
+-        "Return a tuple of process memory information"},
+-    {"get_process_cwd", get_process_cwd, METH_VARARGS,
+-        "Return process current working directory"},
+-    {"suspend_process", suspend_process, METH_VARARGS,
+-        "Suspend a process"},
+-    {"resume_process", resume_process, METH_VARARGS,
+-        "Resume a process"},
+-    {"get_process_open_files", get_process_open_files, METH_VARARGS,
+-        "Return files opened by process"},
+-    {"get_process_username", get_process_username, METH_VARARGS,
+-        "Return the username of a process"},
+-    {"get_process_connections", get_process_connections, METH_VARARGS,
+-        "Return the network connections of a process"},
+-    {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
+-        "Return the network connections of a process"},
+-    {"get_process_threads", get_process_threads, METH_VARARGS,
+-        "Return process threads information as a list of tuple"},
+-    {"process_wait", process_wait, METH_VARARGS,
+-        "Wait for process to terminate and return its exit code."},
+-    {"get_process_priority", get_process_priority, METH_VARARGS,
+-        "Return process priority."},
+-    {"set_process_priority", set_process_priority, METH_VARARGS,
+-        "Set process priority."},
+-#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+-    {"get_process_io_priority", get_process_io_priority, METH_VARARGS,
+-        "Return process IO priority."},
+-    {"set_process_io_priority", set_process_io_priority, METH_VARARGS,
+-        "Set process IO priority."},
+-#endif
+-    {"get_process_cpu_affinity", get_process_cpu_affinity, METH_VARARGS,
+-        "Return process CPU affinity as a bitmask."},
+-    {"set_process_cpu_affinity", set_process_cpu_affinity, METH_VARARGS,
+-        "Set process CPU affinity."},
+-    {"get_process_io_counters", get_process_io_counters, METH_VARARGS,
+-        "Get process I/O counters."},
+-    {"is_process_suspended", is_process_suspended, METH_VARARGS,
+-        "Return True if one of the process threads is in a suspended state"},
+-    {"get_process_num_handles", get_process_num_handles, METH_VARARGS,
+-        "Return the number of handles opened by process."},
+-    {"get_process_num_ctx_switches", get_process_num_ctx_switches, METH_VARARGS,
+-        "Return the number of context switches performed by process."},
+-    {"get_process_memory_maps", get_process_memory_maps, METH_VARARGS,
+-        "Return a list of process's memory mappings"},
+-
+-    // --- alternative pinfo interface
+-    {"get_process_cpu_times_2", get_process_cpu_times_2, METH_VARARGS,
+-        "Alternative implementation"},
+-    {"get_process_create_time_2", get_process_create_time_2, METH_VARARGS,
+-        "Alternative implementation"},
+-    {"get_process_num_handles_2", get_process_num_handles_2, METH_VARARGS,
+-        "Alternative implementation"},
+-    {"get_process_io_counters_2", get_process_io_counters_2, METH_VARARGS,
+-        "Alternative implementation"},
+-    {"get_process_memory_info_2", get_process_memory_info_2, METH_VARARGS,
+-        "Alternative implementation"},
+-
+-    // --- system-related functions
+-
+-    {"get_pid_list", get_pid_list, METH_VARARGS,
+-        "Returns a list of PIDs currently running on the system"},
+-    {"pid_exists", pid_exists, METH_VARARGS,
+-        "Determine if the process exists in the current process list."},
+-    {"get_num_cpus", get_num_cpus, METH_VARARGS,
+-        "Returns the number of CPUs on the system"},
+-    {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
+-        "Return the system boot time expressed in seconds since the epoch."},
+-    {"get_virtual_mem", get_virtual_mem, METH_VARARGS,
+-        "Return the total amount of physical memory, in bytes"},
+-    {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
+-        "Return system per-cpu times as a list of tuples"},
+-    {"get_disk_usage", get_disk_usage, METH_VARARGS,
+-        "Return path's disk total and free as a Python tuple."},
+-    {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
+-        "Return dict of tuples of networks I/O information."},
+-    {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
+-         "Return dict of tuples of disks I/O information."},
+-    {"get_system_users", get_system_users, METH_VARARGS,
+-        "Return a list of currently connected users."},
+-    {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
+-        "Return disk partitions."},
+-
+-
+-     // --- windows API bindings
+-    {"win32_QueryDosDevice", win32_QueryDosDevice, METH_VARARGS,
+-        "QueryDosDevice binding"},
+-
+-    {NULL, NULL, 0, NULL}
+-};
+-
+-
+-struct module_state {
+-    PyObject *error;
+-};
+-
+-#if PY_MAJOR_VERSION >= 3
+-    #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+-#else
+-    #define GETSTATE(m) (&_state)
+-    static struct module_state _state;
+-#endif
+-
+-#if PY_MAJOR_VERSION >= 3
+-
+-    static int psutil_mswindows_traverse(PyObject *m, visitproc visit, void *arg) {
+-        Py_VISIT(GETSTATE(m)->error);
+-        return 0;
+-    }
+-
+-    static int psutil_mswindows_clear(PyObject *m) {
+-        Py_CLEAR(GETSTATE(m)->error);
+-        return 0;
+-    }
+-
+-    static struct PyModuleDef moduledef = {
+-            PyModuleDef_HEAD_INIT,
+-            "psutil_mswindows",
+-            NULL,
+-            sizeof(struct module_state),
+-            PsutilMethods,
+-            NULL,
+-            psutil_mswindows_traverse,
+-            psutil_mswindows_clear,
+-            NULL
+-    };
+-
+-#define INITERROR return NULL
+-
+-    PyObject* PyInit__psutil_mswindows(void)
+-
+-#else
+-    #define INITERROR return
+-    void init_psutil_mswindows(void)
+-#endif
+-{
+-    struct module_state *st = NULL;
+-#if PY_MAJOR_VERSION >= 3
+-    PyObject *module = PyModule_Create(&moduledef);
+-#else
+-    PyObject *module = Py_InitModule("_psutil_mswindows", PsutilMethods);
+-#endif
+-
+-    if (module == NULL) {
+-        INITERROR;
+-    }
+-
+-    st = GETSTATE(module);
+-    st->error = PyErr_NewException("_psutil_mswindow.Error", NULL, NULL);
+-    if (st->error == NULL) {
+-        Py_DECREF(module);
+-        INITERROR;
+-    }
+-
+-    // Public constants
+-    // http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx
+-    PyModule_AddIntConstant(module, "ABOVE_NORMAL_PRIORITY_CLASS",
+-                                     ABOVE_NORMAL_PRIORITY_CLASS);
+-    PyModule_AddIntConstant(module, "BELOW_NORMAL_PRIORITY_CLASS",
+-                                     BELOW_NORMAL_PRIORITY_CLASS);
+-    PyModule_AddIntConstant(module, "HIGH_PRIORITY_CLASS",
+-                                     HIGH_PRIORITY_CLASS);
+-    PyModule_AddIntConstant(module, "IDLE_PRIORITY_CLASS",
+-                                     IDLE_PRIORITY_CLASS);
+-    PyModule_AddIntConstant(module, "NORMAL_PRIORITY_CLASS",
+-                                     NORMAL_PRIORITY_CLASS);
+-    PyModule_AddIntConstant(module, "REALTIME_PRIORITY_CLASS",
+-                                     REALTIME_PRIORITY_CLASS);
+-    // private constants
+-    PyModule_AddIntConstant(module, "INFINITE", INFINITE);
+-    PyModule_AddIntConstant(module, "ERROR_ACCESS_DENIED", ERROR_ACCESS_DENIED);
+-    SetSeDebug();
+-
+-#if PY_MAJOR_VERSION >= 3
+-    return module;
+-#endif
+-}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_mswindows.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_mswindows.h	1969-12-31 16:00:00.000000000 -0800
+@@ -1,71 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Windows platform-specific module methods for _psutil_mswindows
+- */
+-
+-#include <Python.h>
+-#include <windows.h>
+-
+-// --- per-process functions
+-
+-static PyObject* get_process_name(PyObject* self, PyObject* args);
+-static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
+-static PyObject* get_process_exe(PyObject* self, PyObject* args);
+-static PyObject* get_process_ppid(PyObject* self, PyObject* args);
+-static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* get_process_create_time(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
+-static PyObject* get_process_cwd(PyObject* self, PyObject* args);
+-static PyObject* get_process_open_files(PyObject* self, PyObject* args);
+-static PyObject* get_process_username(PyObject* self, PyObject* args);
+-static PyObject* get_process_connections(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_priority(PyObject* self, PyObject* args);
+-static PyObject* set_process_priority(PyObject* self, PyObject* args);
+-#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+-static PyObject* get_process_io_priority(PyObject* self, PyObject* args);
+-static PyObject* set_process_io_priority(PyObject* self, PyObject* args);
+-#endif
+-static PyObject* get_process_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_process_cpu_affinity(PyObject* self, PyObject* args);
+-static PyObject* set_process_cpu_affinity(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_handles(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_ctx_switches(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
+-
+-static PyObject* get_process_cpu_times_2(PyObject* self, PyObject* args);
+-static PyObject* get_process_create_time_2(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_handles_2(PyObject* self, PyObject* args);
+-static PyObject* get_process_io_counters_2(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_info_2(PyObject* self, PyObject* args);
+-
+-static PyObject* suspend_process(PyObject* self, PyObject* args);
+-static PyObject* resume_process(PyObject* self, PyObject* args);
+-static PyObject* is_process_suspended(PyObject* self, PyObject* args);
+-static PyObject* process_wait(PyObject* self, PyObject* args);
+-static PyObject* kill_process(PyObject* self, PyObject* args);
+-
+-// --- system-related functions
+-
+-static PyObject* get_pid_list(PyObject* self, PyObject* args);
+-static PyObject* get_num_cpus(PyObject* self, PyObject* args);
+-static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
+-static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
+-static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* pid_exists(PyObject* self, PyObject* args);
+-static PyObject* get_disk_usage(PyObject* self, PyObject* args);
+-static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
+-static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_system_users(PyObject* self, PyObject* args);
+-
+-// --- windows API bindings
+-
+-static PyObject* win32_QueryDosDevice(PyObject* self, PyObject* args);
+-
+-// --- internal
+-int suspend_resume_process(DWORD pid, int suspend);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_osx.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_osx.c	2015-06-17 19:33:33.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+@@ -68,8 +68,8 @@
+ /*
+  * Return a Python list of all the PIDs running on the system.
+  */
+-static PyObject*
+-get_pid_list(PyObject* self, PyObject* args)
++static PyObject *
++psutil_pids(PyObject *self, PyObject *args)
+ {
+     kinfo_proc *proclist = NULL;
+     kinfo_proc *orig_address = NULL;
+@@ -82,14 +82,15 @@
+         return NULL;
+ 
+     if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
+-        PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list.");
++        PyErr_SetString(PyExc_RuntimeError,
++                        "failed to retrieve process list.");
+         goto error;
+     }
+ 
+     if (num_processes > 0) {
+         // save the address of proclist so we can free it later
+         orig_address = proclist;
+-        for (idx=0; idx < num_processes; idx++) {
++        for (idx = 0; idx < num_processes; idx++) {
+             pid = Py_BuildValue("i", proclist->kp_proc.p_pid);
+             if (!pid)
+                 goto error;
+@@ -114,17 +115,15 @@
+ /*
+  * Return process name from kinfo_proc as a Python string.
+  */
+-static PyObject*
+-get_process_name(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_name(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("s", kp.kp_proc.p_comm);
+ }
+ 
+@@ -132,15 +131,14 @@
+ /*
+  * Return process current working directory.
+  */
+-static PyObject*
+-get_process_cwd(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cwd(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct proc_vnodepathinfo pathinfo;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+ 
+     if (! psutil_proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, &pathinfo,
+                               sizeof(pathinfo)))
+@@ -154,40 +152,37 @@
+ /*
+  * Return path of the process executable.
+  */
+-static PyObject*
+-get_process_exe(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_exe(PyObject *self, PyObject *args)
+ {
+     long pid;
+     char buf[PATH_MAX];
+     int ret;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+     ret = proc_pidpath(pid, &buf, sizeof(buf));
+     if (ret == 0) {
+-        if (! psutil_pid_exists(pid)) {
++        if (! psutil_pid_exists(pid))
+             return NoSuchProcess();
+-        }
+-        else {
++        else
+             return AccessDenied();
+-        }
+     }
+     return Py_BuildValue("s", buf);
+ }
+ 
++
+ /*
+  * Return process cmdline as a Python list of cmdline arguments.
+  */
+-static PyObject*
+-get_process_cmdline(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cmdline(PyObject *self, PyObject *args)
+ {
+     long pid;
+-    PyObject* arglist = NULL;
++    PyObject *arglist = NULL;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+ 
+     // get the commandline, defined in arch/osx/process_info.c
+     arglist = psutil_get_arg_list(pid);
+@@ -198,17 +193,15 @@
+ /*
+  * Return process parent pid from kinfo_proc as a Python integer.
+  */
+-static PyObject*
+-get_process_ppid(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_ppid(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid);
+ }
+ 
+@@ -216,57 +209,53 @@
+ /*
+  * Return process real uid from kinfo_proc as a Python integer.
+  */
+-static PyObject*
+-get_process_uids(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_uids(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("lll", (long)kp.kp_eproc.e_pcred.p_ruid,
+-                                (long)kp.kp_eproc.e_ucred.cr_uid,
+-                                (long)kp.kp_eproc.e_pcred.p_svuid);
++    return Py_BuildValue("lll",
++                         (long)kp.kp_eproc.e_pcred.p_ruid,
++                         (long)kp.kp_eproc.e_ucred.cr_uid,
++                         (long)kp.kp_eproc.e_pcred.p_svuid);
+ }
+ 
+ 
+ /*
+  * Return process real group id from ki_comm as a Python integer.
+  */
+-static PyObject*
+-get_process_gids(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_gids(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+-    return Py_BuildValue("lll", (long)kp.kp_eproc.e_pcred.p_rgid,
+-                                (long)kp.kp_eproc.e_ucred.cr_groups[0],
+-                                (long)kp.kp_eproc.e_pcred.p_svgid);
++    return Py_BuildValue("lll",
++                         (long)kp.kp_eproc.e_pcred.p_rgid,
++                         (long)kp.kp_eproc.e_ucred.cr_groups[0],
++                         (long)kp.kp_eproc.e_pcred.p_svgid);
+ }
+ 
+ 
+ /*
+  * Return process controlling terminal number as an integer.
+  */
+-static PyObject*
+-get_process_tty_nr(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_tty_nr(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("i", kp.kp_eproc.e_tdev);
+ }
+ 
+@@ -275,8 +264,8 @@
+  * Return a list of tuples for every process memory maps.
+  * 'procstat' cmdline utility has been used as an example.
+  */
+-static PyObject*
+-get_process_memory_maps(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_memory_maps(PyObject *self, PyObject *args)
+ {
+     char buf[PATH_MAX];
+     char addr_str[34];
+@@ -284,20 +273,19 @@
+     int pagesize = getpagesize();
+     long pid;
+     kern_return_t err = KERN_SUCCESS;
+-    mach_port_t task;
++    mach_port_t task = MACH_PORT_NULL;
+     uint32_t depth = 1;
+     vm_address_t address = 0;
+     vm_size_t size = 0;
+ 
+-    PyObject* py_tuple = NULL;
+-    PyObject* py_list = PyList_New(0);
++    PyObject *py_tuple = NULL;
++    PyObject *py_list = PyList_New(0);
+ 
+     if (py_list == NULL)
+         return NULL;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    }
+ 
+     err = task_for_pid(mach_task_self(), pid, &task);
+ 
+@@ -320,11 +308,8 @@
+ 
+         err = vm_region_recurse_64(task, &address, &size, &depth,
+                                    (vm_region_info_64_t)&info, &count);
+-
+-        if (err == KERN_INVALID_ADDRESS) {
++        if (err == KERN_INVALID_ADDRESS)
+             break;
+-        }
+-
+         if (info.is_submap) {
+             depth++;
+         }
+@@ -343,8 +328,6 @@
+                     (info.max_protection & VM_PROT_WRITE) ? 'w' : '-',
+                     (info.max_protection & VM_PROT_EXECUTE) ? 'x' : '-');
+ 
+-            address += size;
+-
+             err = proc_regionfilename(pid, address, buf, sizeof(buf));
+ 
+             if (info.share_mode == SM_COW && info.ref_count == 1) {
+@@ -353,38 +336,37 @@
+             }
+ 
+             if (strlen(buf) == 0) {
+-                switch(info.share_mode) {
+-                /*
+-                case SM_LARGE_PAGE:
+-                    // Treat SM_LARGE_PAGE the same as SM_PRIVATE
+-                    // since they are not shareable and are wired.
+-                */
+-                case SM_COW:
+-                    strcpy(buf, "[cow]");
+-                    break;
+-                case SM_PRIVATE:
+-                    strcpy(buf, "[prv]");
+-                    break;
+-                case SM_EMPTY:
+-                    strcpy(buf, "[nul]");
+-                    break;
+-                case SM_SHARED:
+-                case SM_TRUESHARED:
+-                    strcpy(buf, "[shm]");
+-                    break;
+-                case SM_PRIVATE_ALIASED:
+-                    strcpy(buf, "[ali]");
+-                    break;
+-                case SM_SHARED_ALIASED:
+-                    strcpy(buf, "[s/a]");
+-                    break;
+-                default:
+-                    strcpy(buf, "[???]");
++                switch (info.share_mode) {
++                    // case SM_LARGE_PAGE:
++                        // Treat SM_LARGE_PAGE the same as SM_PRIVATE
++                        // since they are not shareable and are wired.
++                    case SM_COW:
++                        strcpy(buf, "[cow]");
++                        break;
++                    case SM_PRIVATE:
++                        strcpy(buf, "[prv]");
++                        break;
++                    case SM_EMPTY:
++                        strcpy(buf, "[nul]");
++                        break;
++                    case SM_SHARED:
++                    case SM_TRUESHARED:
++                        strcpy(buf, "[shm]");
++                        break;
++                    case SM_PRIVATE_ALIASED:
++                        strcpy(buf, "[ali]");
++                        break;
++                    case SM_SHARED_ALIASED:
++                        strcpy(buf, "[s/a]");
++                        break;
++                    default:
++                        strcpy(buf, "[???]");
+                 }
+             }
+ 
+-            py_tuple = Py_BuildValue("sssIIIIIH",
+-                addr_str,                                 // "start-end" address
++            py_tuple = Py_BuildValue(
++                "sssIIIIIH",
++                addr_str,                                 // "start-end"address
+                 perms,                                    // "rwx" permissions
+                 buf,                                      // path
+                 info.pages_resident * pagesize,           // rss
+@@ -400,6 +382,9 @@
+                 goto error;
+             Py_DECREF(py_tuple);
+         }
++
++        // increment address for the next map/file
++        address += size;
+     }
+ 
+     if (task != MACH_PORT_NULL)
+@@ -417,25 +402,39 @@
+ 
+ 
+ /*
+- * Return a Python integer indicating the number of CPUs on the system.
++ * Return the number of logical CPUs in the system.
++ * XXX this could be shared with BSD.
+  */
+-static PyObject*
+-get_num_cpus(PyObject* self, PyObject* args)
++static PyObject *
++psutil_cpu_count_logical(PyObject *self, PyObject *args)
+ {
+     int mib[2];
+     int ncpu;
+     size_t len;
+-
+     mib[0] = CTL_HW;
+     mib[1] = HW_NCPU;
+     len = sizeof(ncpu);
+ 
+-    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
+-        return NULL;
+-    }
++    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
++        Py_RETURN_NONE;  // mimic os.cpu_count()
++    else
++        return Py_BuildValue("i", ncpu);
++}
++
+ 
+-    return Py_BuildValue("i", ncpu);
++/*
++ * Return the number of physical CPUs in the system.
++ */
++static PyObject *
++psutil_cpu_count_phys(PyObject *self, PyObject *args)
++{
++    int num;
++    size_t size = sizeof(int);
++
++    if (sysctlbyname("hw.physicalcpu", &num, &size, NULL, 0))
++        Py_RETURN_NONE;  // mimic os.cpu_count()
++    else
++        return Py_BuildValue("i", num);
+ }
+ 
+ 
+@@ -444,17 +443,16 @@
+ /*
+  * Return a Python tuple (user_time, kernel_time)
+  */
+-static PyObject*
+-get_process_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_cpu_times(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct proc_taskinfo pti;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
++    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
+         return NULL;
+-    }
+     return Py_BuildValue("(dd)",
+                          (float)pti.pti_total_user / 1000000000.0,
+                          (float)pti.pti_total_system / 1000000000.0);
+@@ -465,17 +463,15 @@
+  * Return a Python float indicating the process create time expressed in
+  * seconds since the epoch.
+  */
+-static PyObject*
+-get_process_create_time(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_create_time(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime));
+ }
+ 
+@@ -483,29 +479,27 @@
+ /*
+  * Return extended memory info about a process.
+  */
+-static PyObject*
+-get_process_memory_info(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_memory_info(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct proc_taskinfo pti;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
++    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
+         return NULL;
+-    }
+-
+     // Note: determining other memory stats on OSX is a mess:
+     // http://www.opensource.apple.com/source/top/top-67/libtop.c?txt
+     // I just give up...
+-    //struct proc_regioninfo pri;
+-    //psutil_proc_pidinfo(pid, PROC_PIDREGIONINFO, &pri, sizeof(pri))
+-
+-    return Py_BuildValue("(KKkk)",
+-        pti.pti_resident_size,      // resident memory size (rss)
+-        pti.pti_virtual_size,       // virtual memory size (vms)
+-        pti.pti_faults,             // number of page faults (pages)
+-        pti.pti_pageins             // number of actual pageins (pages)
++    // struct proc_regioninfo pri;
++    // psutil_proc_pidinfo(pid, PROC_PIDREGIONINFO, &pri, sizeof(pri))
++    return Py_BuildValue(
++        "(KKkk)",
++        pti.pti_resident_size,  // resident memory size (rss)
++        pti.pti_virtual_size,   // virtual memory size (vms)
++        pti.pti_faults,         // number of page faults (pages)
++        pti.pti_pageins         // number of actual pageins (pages)
+     );
+ }
+ 
+@@ -513,17 +507,16 @@
+ /*
+  * Return number of threads used by process as a Python integer.
+  */
+-static PyObject*
+-get_process_num_threads(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_threads(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct proc_taskinfo pti;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
++    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
+         return NULL;
+-    }
+     return Py_BuildValue("k", pti.pti_threadnum);
+ }
+ 
+@@ -531,17 +524,16 @@
+ /*
+  * Return the number of context switches performed by process.
+  */
+-static PyObject*
+-get_process_num_ctx_switches(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct proc_taskinfo pti;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
++    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti)))
+         return NULL;
+-    }
+     // unvoluntary value seems not to be available;
+     // pti.pti_csw probably refers to the sum of the two (getrusage()
+     // numbers seems to confirm this theory).
+@@ -552,8 +544,8 @@
+ /*
+  * Return system virtual memory stats
+  */
+-static PyObject*
+-get_virtual_mem(PyObject* self, PyObject* args)
++static PyObject *
++psutil_virtual_mem(PyObject *self, PyObject *args)
+ {
+ 
+     int      mib[2];
+@@ -561,24 +553,24 @@
+     size_t   len = sizeof(total);
+     vm_statistics_data_t vm;
+     int pagesize = getpagesize();
+-
+     // physical mem
+     mib[0] = CTL_HW;
+     mib[1] = HW_MEMSIZE;
++
+     if (sysctl(mib, 2, &total, &len, NULL, 0)) {
+         if (errno != 0)
+-            PyErr_SetFromErrno(0);
++            PyErr_SetFromErrno(PyExc_OSError);
+         else
+             PyErr_Format(PyExc_RuntimeError, "sysctl(HW_MEMSIZE) failed");
+         return NULL;
+     }
+ 
+     // vm
+-    if (!psutil_sys_vminfo(&vm)) {
++    if (!psutil_sys_vminfo(&vm))
+         return NULL;
+-    }
+ 
+-    return Py_BuildValue("KKKKK",
++    return Py_BuildValue(
++        "KKKKK",
+         total,
+         (unsigned long long) vm.active_count * pagesize,
+         (unsigned long long) vm.inactive_count * pagesize,
+@@ -591,8 +583,8 @@
+ /*
+  * Return stats about swap memory.
+  */
+-static PyObject*
+-get_swap_mem(PyObject* self, PyObject* args)
++static PyObject *
++psutil_swap_mem(PyObject *self, PyObject *args)
+ {
+     int mib[2];
+     size_t size;
+@@ -605,65 +597,67 @@
+     size = sizeof(totals);
+     if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) {
+         if (errno != 0)
+-            PyErr_SetFromErrno(0);
++            PyErr_SetFromErrno(PyExc_OSError);
+         else
+             PyErr_Format(PyExc_RuntimeError, "sysctl(VM_SWAPUSAGE) failed");
+         return NULL;
+     }
+-    if (!psutil_sys_vminfo(&vmstat)) {
++    if (!psutil_sys_vminfo(&vmstat))
+         return NULL;
+-    }
+ 
+-    return Py_BuildValue("LLLKK",
+-                         totals.xsu_total,
+-                         totals.xsu_used,
+-                         totals.xsu_avail,
+-                         (unsigned long long)vmstat.pageins * pagesize,
+-                         (unsigned long long)vmstat.pageouts * pagesize);
++    return Py_BuildValue(
++        "LLLKK",
++        totals.xsu_total,
++        totals.xsu_used,
++        totals.xsu_avail,
++        (unsigned long long)vmstat.pageins * pagesize,
++        (unsigned long long)vmstat.pageouts * pagesize);
+ }
+ 
+ 
+ /*
+  * Return a Python tuple representing user, kernel and idle CPU times
+  */
+-static PyObject*
+-get_system_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_cpu_times(PyObject *self, PyObject *args)
+ {
+-    mach_msg_type_number_t  count = HOST_CPU_LOAD_INFO_COUNT;
++    mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+     kern_return_t error;
+     host_cpu_load_info_data_t r_load;
+ 
+     mach_port_t host_port = mach_host_self();
+-    error = host_statistics(host_port, HOST_CPU_LOAD_INFO, (host_info_t)&r_load, &count);
+-    if (error != KERN_SUCCESS) {
++    error = host_statistics(host_port, HOST_CPU_LOAD_INFO,
++                            (host_info_t)&r_load, &count);
++    if (error != KERN_SUCCESS)
+         return PyErr_Format(PyExc_RuntimeError,
+-                "Error in host_statistics(): %s", mach_error_string(error));
+-    }
++                            "Error in host_statistics(): %s",
++                            mach_error_string(error));
+     mach_port_deallocate(mach_task_self(), host_port);
+ 
+-    return Py_BuildValue("(dddd)",
+-                         (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
+-                         (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
+-                         (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
+-                         (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
+-                         );
++    return Py_BuildValue(
++        "(dddd)",
++        (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
++        (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
++        (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
++        (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
++    );
+ }
+ 
+ 
+ /*
+  * Return a Python list of tuple representing per-cpu times
+  */
+-static PyObject*
+-get_system_per_cpu_times(PyObject* self, PyObject* args)
++static PyObject *
++psutil_per_cpu_times(PyObject *self, PyObject *args)
+ {
+     natural_t cpu_count;
+     processor_info_array_t info_array;
+     mach_msg_type_number_t info_count;
+     kern_return_t error;
+-    processor_cpu_load_info_data_t* cpu_load_info = NULL;
++    processor_cpu_load_info_data_t *cpu_load_info = NULL;
+     int i, ret;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_cputime = NULL;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_cputime = NULL;
+ 
+     if (py_retlist == NULL)
+         return NULL;
+@@ -678,15 +672,16 @@
+     }
+     mach_port_deallocate(mach_task_self(), host_port);
+ 
+-    cpu_load_info = (processor_cpu_load_info_data_t*) info_array;
++    cpu_load_info = (processor_cpu_load_info_data_t *) info_array;
+ 
+     for (i = 0; i < cpu_count; i++) {
+-        py_cputime = Py_BuildValue("(dddd)",
+-               (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK,
+-               (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
+-               (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
+-               (double)cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
+-              );
++        py_cputime = Py_BuildValue(
++            "(dddd)",
++            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK,
++            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
++            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
++            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
++        );
+         if (!py_cputime)
+             goto error;
+         if (PyList_Append(py_retlist, py_cputime))
+@@ -696,9 +691,8 @@
+ 
+     ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
+                         info_count * sizeof(int));
+-    if (ret != KERN_SUCCESS) {
++    if (ret != KERN_SUCCESS)
+         PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+-    }
+     return py_retlist;
+ 
+ error:
+@@ -707,9 +701,8 @@
+     if (cpu_load_info != NULL) {
+         ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
+                             info_count * sizeof(int));
+-        if (ret != KERN_SUCCESS) {
++        if (ret != KERN_SUCCESS)
+             PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+-        }
+     }
+     return NULL;
+ }
+@@ -719,17 +712,17 @@
+  * Return a Python float indicating the system boot time expressed in
+  * seconds since the epoch.
+  */
+-static PyObject*
+-get_system_boot_time(PyObject* self, PyObject* args)
++static PyObject *
++psutil_boot_time(PyObject *self, PyObject *args)
+ {
+-    /* fetch sysctl "kern.boottime" */
++    // fetch sysctl "kern.boottime"
+     static int request[2] = { CTL_KERN, KERN_BOOTTIME };
+     struct timeval result;
+     size_t result_len = sizeof result;
+     time_t boot_time = 0;
+ 
+     if (sysctl(request, 2, &result, &result_len, NULL, 0) == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         return NULL;
+     }
+     boot_time = result.tv_sec;
+@@ -741,8 +734,8 @@
+  * Return a list of tuples including device, mount point and fs type
+  * for all partitions mounted on the system.
+  */
+-static PyObject*
+-get_disk_partitions(PyObject* self, PyObject* args)
++static PyObject *
++psutil_disk_partitions(PyObject *self, PyObject *args)
+ {
+     int num;
+     int i;
+@@ -750,8 +743,8 @@
+     uint64_t flags;
+     char opts[400];
+     struct statfs *fs = NULL;
+-    PyObject* py_retlist = PyList_New(0);
+-    PyObject* py_tuple = NULL;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
+ 
+     if (py_retlist == NULL)
+         return NULL;
+@@ -761,7 +754,7 @@
+     num = getfsstat(NULL, 0, MNT_NOWAIT);
+     Py_END_ALLOW_THREADS
+     if (num == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -776,7 +769,7 @@
+     num = getfsstat(fs, len, MNT_NOWAIT);
+     Py_END_ALLOW_THREADS
+     if (num == -1) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -836,10 +829,11 @@
+         if (flags & MNT_CMDFLAGS)
+             strlcat(opts, ",cmdflags", sizeof(opts));
+ 
+-        py_tuple = Py_BuildValue("(ssss)", fs[i].f_mntfromname,  // device
+-                                           fs[i].f_mntonname,    // mount point
+-                                           fs[i].f_fstypename,   // fs type
+-                                           opts);                // options
++        py_tuple = Py_BuildValue(
++            "(ssss)", fs[i].f_mntfromname,  // device
++            fs[i].f_mntonname,    // mount point
++            fs[i].f_fstypename,   // fs type
++            opts);                // options
+         if (!py_tuple)
+             goto error;
+         if (PyList_Append(py_retlist, py_tuple))
+@@ -862,17 +856,15 @@
+ /*
+  * Return process status as a Python integer.
+  */
+-static PyObject*
+-get_process_status(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_status(PyObject *self, PyObject *args)
+ {
+     long pid;
+     struct kinfo_proc kp;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+-    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
++    if (psutil_get_kinfo_proc(pid, &kp) == -1)
+         return NULL;
+-    }
+     return Py_BuildValue("i", (int)kp.kp_proc.p_stat);
+ }
+ 
+@@ -880,45 +872,43 @@
+ /*
+  * Return process threads
+  */
+-static PyObject*
+-get_process_threads(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_threads(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int err, j, ret;
+     kern_return_t kr;
+     unsigned int info_count = TASK_BASIC_INFO_COUNT;
+-    mach_port_t task;
++    mach_port_t task = MACH_PORT_NULL;
+     struct task_basic_info tasks_info;
+     thread_act_port_array_t thread_list = NULL;
+-    thread_info_data_t thinfo;
++    thread_info_data_t thinfo_basic;
+     thread_basic_info_t basic_info_th;
+     mach_msg_type_number_t thread_count, thread_info_count;
+ 
+-    PyObject* retList = PyList_New(0);
+-    PyObject* pyTuple = NULL;
++    PyObject *retList = PyList_New(0);
++    PyObject *pyTuple = NULL;
+ 
+     if (retList == NULL)
+         return NULL;
+ 
+     // the argument passed should be a process id
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    }
+ 
+     // task_for_pid() requires special privileges
+     err = task_for_pid(mach_task_self(), pid, &task);
+     if (err != KERN_SUCCESS) {
+-        if (! psutil_pid_exists(pid)) {
++        if (! psutil_pid_exists(pid))
+             NoSuchProcess();
+-        }
+-        else {
++        else
+             AccessDenied();
+-        }
+         goto error;
+     }
+ 
+     info_count = TASK_BASIC_INFO_COUNT;
+-    err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count);
++    err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info,
++                    &info_count);
+     if (err != KERN_SUCCESS) {
+         // errcode 4 is "invalid argument" (access denied)
+         if (err == 4) {
+@@ -926,7 +916,8 @@
+         }
+         else {
+             // otherwise throw a runtime error with appropriate error code
+-            PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed");
++            PyErr_Format(PyExc_RuntimeError,
++                         "task_info(TASK_BASIC_INFO) failed");
+         }
+         goto error;
+     }
+@@ -941,18 +932,20 @@
+         pyTuple = NULL;
+         thread_info_count = THREAD_INFO_MAX;
+         kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
+-                         (thread_info_t)thinfo, &thread_info_count);
++                         (thread_info_t)thinfo_basic, &thread_info_count);
+         if (kr != KERN_SUCCESS) {
+-            PyErr_Format(PyExc_RuntimeError, "thread_info() failed");
++            PyErr_Format(PyExc_RuntimeError,
++                         "thread_info() with flag THREAD_BASIC_INFO failed");
+             goto error;
+         }
+-        basic_info_th = (thread_basic_info_t)thinfo;
+-        // XXX - thread_info structure does not provide any process id;
+-        // the best we can do is assigning an incremental bogus value
+-        pyTuple = Py_BuildValue("Iff", j + 1,
+-                    (float)basic_info_th->user_time.microseconds / 1000000.0,
+-                    (float)basic_info_th->system_time.microseconds / 1000000.0
+-                  );
++
++        basic_info_th = (thread_basic_info_t)thinfo_basic;
++        pyTuple = Py_BuildValue(
++            "Iff",
++            j + 1,
++            (float)basic_info_th->user_time.microseconds / 1000000.0,
++            (float)basic_info_th->system_time.microseconds / 1000000.0
++        );
+         if (!pyTuple)
+             goto error;
+         if (PyList_Append(retList, pyTuple))
+@@ -962,9 +955,8 @@
+ 
+     ret = vm_deallocate(task, (vm_address_t)thread_list,
+                         thread_count * sizeof(int));
+-    if (ret != KERN_SUCCESS) {
++    if (ret != KERN_SUCCESS)
+         PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+-    }
+ 
+     mach_port_deallocate(mach_task_self(), task);
+ 
+@@ -978,9 +970,8 @@
+     if (thread_list != NULL) {
+         ret = vm_deallocate(task, (vm_address_t)thread_list,
+                             thread_count * sizeof(int));
+-        if (ret != KERN_SUCCESS) {
++        if (ret != KERN_SUCCESS)
+             PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+-        }
+     }
+     return NULL;
+ }
+@@ -992,8 +983,8 @@
+  * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
+  * - /usr/include/sys/proc_info.h
+  */
+-static PyObject*
+-get_process_open_files(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_open_files(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int pidinfo_result;
+@@ -1011,14 +1002,14 @@
+     if (retList == NULL)
+         return NULL;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         goto error;
+-    }
+ 
+     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+     if (pidinfo_result <= 0) {
+         // may be be ignored later if errno != 0
+-        PyErr_Format(PyExc_RuntimeError, "proc_pidinfo(PROC_PIDLISTFDS) failed");
++        PyErr_Format(PyExc_RuntimeError,
++                     "proc_pidinfo(PROC_PIDLISTFDS) failed");
+         goto error;
+     }
+ 
+@@ -1031,7 +1022,8 @@
+                                   pidinfo_result);
+     if (pidinfo_result <= 0) {
+         // may be be ignored later if errno != 0
+-        PyErr_Format(PyExc_RuntimeError, "proc_pidinfo(PROC_PIDLISTFDS) failed");
++        PyErr_Format(PyExc_RuntimeError,
++                     "proc_pidinfo(PROC_PIDLISTFDS) failed");
+         goto error;
+     }
+ 
+@@ -1058,19 +1050,21 @@
+                 }
+                 // may be be ignored later if errno != 0
+                 PyErr_Format(PyExc_RuntimeError,
+-                            "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
++                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
+                 goto error;
+             }
+             if (nb < sizeof(vi)) {
+                 PyErr_Format(PyExc_RuntimeError,
+-                 "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)");
++                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
++                             "(buffer mismatch)");
+                 goto error;
+             }
+             // --- /errors checking
+ 
+             // --- construct python list
+-            tuple = Py_BuildValue("(si)", vi.pvip.vip_path,
+-                                          (int)fdp_pointer->proc_fd);
++            tuple = Py_BuildValue("(si)",
++                                  vi.pvip.vip_path,
++                                  (int)fdp_pointer->proc_fd);
+             if (!tuple)
+                 goto error;
+             if (PyList_Append(retList, tuple))
+@@ -1086,56 +1080,19 @@
+ error:
+     Py_XDECREF(tuple);
+     Py_DECREF(retList);
+-    if (fds_pointer != NULL) {
++    if (fds_pointer != NULL)
+         free(fds_pointer);
+-    }
+-    if (errno != 0) {
++    if (errno != 0)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+-    else if (! psutil_pid_exists(pid)) {
++    else if (! psutil_pid_exists(pid))
+         return NoSuchProcess();
+-    }
+-    else {
+-        // exception has already been set earlier
+-        return NULL;
+-    }
++    else
++        return NULL;  // exception has already been set earlier
+ }
+ 
+ 
+-/*
+- * mathes Linux net/tcp_states.h:
+- * http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
+- */
+-static char *
+-get_connection_status(int st) {
+-    switch (st) {
+-        case TCPS_CLOSED:
+-            return "CLOSE";
+-        case TCPS_CLOSING:
+-            return "CLOSING";
+-        case TCPS_CLOSE_WAIT:
+-            return "CLOSE_WAIT";
+-        case TCPS_LISTEN:
+-            return "LISTEN";
+-        case TCPS_ESTABLISHED:
+-            return "ESTABLISHED";
+-        case TCPS_SYN_SENT:
+-            return "SYN_SENT";
+-        case TCPS_SYN_RECEIVED:
+-            return "SYN_RECV";
+-        case TCPS_FIN_WAIT_1:
+-            return "FIN_WAIT_1";
+-        case TCPS_FIN_WAIT_2:
+-            return "FIN_WAIT_2";
+-        case TCPS_LAST_ACK:
+-            return "LAST_ACK";
+-        case TCPS_TIME_WAIT:
+-            return "TIME_WAIT";
+-        default:
+-            return "";
+-    }
+-}
+-
++// a signaler for connections without an actual status
++static int PSUTIL_CONN_NONE = 128;
+ 
+ /*
+  * Return process TCP and UDP connections as a list of tuples.
+@@ -1143,8 +1100,8 @@
+  * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
+  * - /usr/include/sys/proc_info.h
+  */
+-static PyObject*
+-get_process_connections(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_connections(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int pidinfo_result;
+@@ -1166,23 +1123,19 @@
+     if (retList == NULL)
+         return NULL;
+ 
+-    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
++    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
+         goto error;
+-    }
+ 
+     if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
+         PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
+         goto error;
+     }
+ 
+-    if (pid == 0) {
++    if (pid == 0)
+         return retList;
+-    }
+-
+     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+-    if (pidinfo_result <= 0) {
++    if (pidinfo_result <= 0)
+         goto error;
+-    }
+ 
+     fds_pointer = malloc(pidinfo_result);
+     if (fds_pointer == NULL) {
+@@ -1192,10 +1145,8 @@
+     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
+                                   pidinfo_result);
+ 
+-    if (pidinfo_result <= 0) {
++    if (pidinfo_result <= 0)
+         goto error;
+-    }
+-
+     iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
+ 
+     for (i = 0; i < iterations; i++) {
+@@ -1207,8 +1158,8 @@
+ 
+         if (fdp_pointer->proc_fdtype == PROX_FDTYPE_SOCKET)
+         {
+-            nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd, PROC_PIDFDSOCKETINFO,
+-                                &si, sizeof(si));
++            nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd,
++                                PROC_PIDFDSOCKETINFO, &si, sizeof(si));
+ 
+             // --- errors checking
+             if (nb <= 0) {
+@@ -1216,29 +1167,28 @@
+                     // let's assume socket has been closed
+                     continue;
+                 }
+-                if (errno != 0) {
++                if (errno != 0)
+                     PyErr_SetFromErrno(PyExc_OSError);
+-                }
+-                else {
+-                    PyErr_Format(PyExc_RuntimeError,
+-                                 "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
+-                }
++                else
++                    PyErr_Format(
++                        PyExc_RuntimeError,
++                        "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
+                 goto error;
+             }
+             if (nb < sizeof(si)) {
+                 PyErr_Format(PyExc_RuntimeError,
+-                 "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)");
++                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
++                             "(buffer mismatch)");
+                 goto error;
+             }
+             // --- /errors checking
+ 
+             //
+-            int fd, family, type, lport, rport;
++            int fd, family, type, lport, rport, state;
+             char lip[200], rip[200];
+-            char *state;
+             int inseq;
+-            PyObject* _family;
+-            PyObject* _type;
++            PyObject *_family;
++            PyObject *_type;
+ 
+             fd = (int)fdp_pointer->proc_fd;
+             family = si.psi.soi_family;
+@@ -1248,15 +1198,13 @@
+             _family = PyLong_FromLong((long)family);
+             inseq = PySequence_Contains(af_filter, _family);
+             Py_DECREF(_family);
+-            if (inseq == 0) {
++            if (inseq == 0)
+                 continue;
+-            }
+             _type = PyLong_FromLong((long)type);
+             inseq = PySequence_Contains(type_filter, _type);
+             Py_DECREF(_type);
+-            if (inseq == 0) {
++            if (inseq == 0)
+                 continue;
+-            }
+ 
+             if (errno != 0) {
+                 PyErr_SetFromErrno(PyExc_OSError);
+@@ -1266,20 +1214,24 @@
+             if ((family == AF_INET) || (family == AF_INET6)) {
+                 if (family == AF_INET) {
+                     inet_ntop(AF_INET,
+-                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_46.i46a_addr4,
++                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
++                                  insi_laddr.ina_46.i46a_addr4,
+                               lip,
+                               sizeof(lip));
+                     inet_ntop(AF_INET,
+-                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_46.i46a_addr4,
++                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr. \
++                                  ina_46.i46a_addr4,
+                               rip,
+                               sizeof(rip));
+                 }
+                 else {
+                     inet_ntop(AF_INET6,
+-                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_6,
++                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
++                                  insi_laddr.ina_6,
+                               lip, sizeof(lip));
+                     inet_ntop(AF_INET6,
+-                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_6,
++                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
++                                  insi_faddr.ina_6,
+                               rip, sizeof(rip));
+                 }
+ 
+@@ -1291,29 +1243,24 @@
+ 
+                 lport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
+                 rport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
+-                if (type == SOCK_STREAM) {
+-                    state = get_connection_status((int)si.psi.soi_proto.pri_tcp.tcpsi_state);
+-                }
+-
+-                else {
+-                    state = "";
+-                }
++                if (type == SOCK_STREAM)
++                    state = (int)si.psi.soi_proto.pri_tcp.tcpsi_state;
++                else
++                    state = PSUTIL_CONN_NONE;
+ 
+                 laddr = Py_BuildValue("(si)", lip, lport);
+                 if (!laddr)
+                     goto error;
+-                if (rport != 0) {
++                if (rport != 0)
+                     raddr = Py_BuildValue("(si)", rip, rport);
+-                }
+-                else {
++                else
+                     raddr = Py_BuildValue("()");
+-                }
+                 if (!raddr)
+                     goto error;
+ 
+                 // construct the python list
+-                tuple = Py_BuildValue("(iiiNNs)", fd, family, type, laddr, raddr,
+-                                                  state);
++                tuple = Py_BuildValue("(iiiNNi)", fd, family, type, laddr,
++                                      raddr, state);
+                 if (!tuple)
+                     goto error;
+                 if (PyList_Append(retList, tuple))
+@@ -1322,11 +1269,12 @@
+             }
+             else if (family == AF_UNIX) {
+                 // construct the python list
+-                tuple = Py_BuildValue("(iiisss)",
++                tuple = Py_BuildValue(
++                    "(iiissi)",
+                     fd, family, type,
+                     si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path,
+                     si.psi.soi_proto.pri_un.unsi_caddr.ua_sun.sun_path,
+-                    "");
++                    PSUTIL_CONN_NONE);
+                 if (!tuple)
+                     goto error;
+                 if (PyList_Append(retList, tuple))
+@@ -1345,46 +1293,39 @@
+     Py_XDECREF(raddr);
+     Py_DECREF(retList);
+ 
+-    if (fds_pointer != NULL) {
++    if (fds_pointer != NULL)
+         free(fds_pointer);
+-    }
+-    if (errno != 0) {
++    if (errno != 0)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+-    else if (! psutil_pid_exists(pid) ) {
++    else if (! psutil_pid_exists(pid))
+         return NoSuchProcess();
+-    }
+-    else {
++    else
+         return PyErr_Format(PyExc_RuntimeError,
+                             "proc_pidinfo(PROC_PIDLISTFDS) failed");
+-    }
+ }
+ 
+ 
+ /*
+  * Return number of file descriptors opened by process.
+  */
+-static PyObject*
+-get_process_num_fds(PyObject* self, PyObject* args)
++static PyObject *
++psutil_proc_num_fds(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int pidinfo_result;
+     int num;
+     struct proc_fdinfo *fds_pointer;
+ 
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+ 
+     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+-    if (pidinfo_result <= 0) {
++    if (pidinfo_result <= 0)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+ 
+     fds_pointer = malloc(pidinfo_result);
+-    if (fds_pointer == NULL) {
++    if (fds_pointer == NULL)
+         return PyErr_NoMemory();
+-    }
+     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
+                                   pidinfo_result);
+     if (pidinfo_result <= 0) {
+@@ -1401,15 +1342,15 @@
+ /*
+  * Return a Python list of named tuples with overall network I/O information
+  */
+-static PyObject*
+-get_network_io_counters(PyObject* self, PyObject* args)
++static PyObject *
++psutil_net_io_counters(PyObject *self, PyObject *args)
+ {
+     char *buf = NULL, *lim, *next;
+     struct if_msghdr *ifm;
+     int mib[6];
+     size_t len;
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_ifc_info = NULL;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_ifc_info = NULL;
+ 
+     if (py_retdict == NULL)
+         return NULL;
+@@ -1422,7 +1363,7 @@
+     mib[5] = 0;
+ 
+     if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1433,7 +1374,7 @@
+     }
+ 
+     if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+-        PyErr_SetFromErrno(0);
++        PyErr_SetFromErrno(PyExc_OSError);
+         goto error;
+     }
+ 
+@@ -1452,15 +1393,16 @@
+             strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
+             ifc_name[sdl->sdl_nlen] = 0;
+ 
+-            py_ifc_info = Py_BuildValue("(KKKKKKKi)",
+-                                        if2m->ifm_data.ifi_obytes,
+-                                        if2m->ifm_data.ifi_ibytes,
+-                                        if2m->ifm_data.ifi_opackets,
+-                                        if2m->ifm_data.ifi_ipackets,
+-                                        if2m->ifm_data.ifi_ierrors,
+-                                        if2m->ifm_data.ifi_oerrors,
+-                                        if2m->ifm_data.ifi_iqdrops,
+-                                        0);  // dropout not supported
++            py_ifc_info = Py_BuildValue(
++                "(KKKKKKKi)",
++                if2m->ifm_data.ifi_obytes,
++                if2m->ifm_data.ifi_ibytes,
++                if2m->ifm_data.ifi_opackets,
++                if2m->ifm_data.ifi_ipackets,
++                if2m->ifm_data.ifi_ierrors,
++                if2m->ifm_data.ifi_oerrors,
++                if2m->ifm_data.ifi_iqdrops,
++                0);  // dropout not supported
+ 
+             if (!py_ifc_info)
+                 goto error;
+@@ -1488,8 +1430,8 @@
+ /*
+  * Return a Python dict of tuples for disk I/O information
+  */
+-static PyObject*
+-get_disk_io_counters(PyObject* self, PyObject* args)
++static PyObject *
++psutil_disk_io_counters(PyObject *self, PyObject *args)
+ {
+     CFDictionaryRef parent_dict;
+     CFDictionaryRef props_dict;
+@@ -1497,54 +1439,60 @@
+     io_registry_entry_t parent;
+     io_registry_entry_t disk;
+     io_iterator_t disk_list;
+-    PyObject* py_retdict = PyDict_New();
+-    PyObject* py_disk_info = NULL;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_disk_info = NULL;
+ 
+     if (py_retdict == NULL)
+         return NULL;
+ 
+-    /* Get list of disks */
++    // Get list of disks
+     if (IOServiceGetMatchingServices(kIOMasterPortDefault,
+                                      IOServiceMatching(kIOMediaClass),
+                                      &disk_list) != kIOReturnSuccess) {
+-        PyErr_SetString(PyExc_RuntimeError, "Unable to get the list of disks.");
++        PyErr_SetString(PyExc_RuntimeError,
++                        "unable to get the list of disks.");
+         goto error;
+     }
+ 
+-    /* Iterate over disks */
++    // Iterate over disks
+     while ((disk = IOIteratorNext(disk_list)) != 0) {
+         py_disk_info = NULL;
+         parent_dict = NULL;
+         props_dict = NULL;
+         stats_dict = NULL;
+ 
+-        if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent) != kIOReturnSuccess) {
+-            PyErr_SetString(PyExc_RuntimeError, "Unable to get the disk's parent.");
++        if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent)
++                != kIOReturnSuccess) {
++            PyErr_SetString(PyExc_RuntimeError,
++                            "unable to get the disk's parent.");
+             IOObjectRelease(disk);
+             goto error;
+         }
+ 
+         if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) {
+-            if(IORegistryEntryCreateCFProperties(
+-                                     disk,
+-                                     (CFMutableDictionaryRef *) &parent_dict,
+-                                     kCFAllocatorDefault,
+-                                     kNilOptions) != kIOReturnSuccess)
++            if (IORegistryEntryCreateCFProperties(
++                    disk,
++                    (CFMutableDictionaryRef *) &parent_dict,
++                    kCFAllocatorDefault,
++                    kNilOptions
++                ) != kIOReturnSuccess)
+             {
+                 PyErr_SetString(PyExc_RuntimeError,
+-                                "Unable to get the parent's properties.");
++                                "unable to get the parent's properties.");
+                 IOObjectRelease(disk);
+                 IOObjectRelease(parent);
+                 goto error;
+             }
+ 
+-            if (IORegistryEntryCreateCFProperties(parent,
+-                                          (CFMutableDictionaryRef *) &props_dict,
+-                                          kCFAllocatorDefault,
+-                                          kNilOptions) != kIOReturnSuccess)
++            if (IORegistryEntryCreateCFProperties(
++                    parent,
++                    (CFMutableDictionaryRef *) &props_dict,
++                    kCFAllocatorDefault,
++                    kNilOptions
++                ) != kIOReturnSuccess)
+             {
+                 PyErr_SetString(PyExc_RuntimeError,
+-                                "Unable to get the disk properties.");
++                                "unable to get the disk properties.");
+                 CFRelease(props_dict);
+                 IOObjectRelease(disk);
+                 IOObjectRelease(parent);
+@@ -1553,8 +1501,7 @@
+ 
+             const int kMaxDiskNameSize = 64;
+             CFStringRef disk_name_ref = (CFStringRef)CFDictionaryGetValue(
+-                                                    parent_dict,
+-                                                    CFSTR(kIOBSDNameKey));
++                parent_dict, CFSTR(kIOBSDNameKey));
+             char disk_name[kMaxDiskNameSize];
+ 
+             CFStringGetCString(disk_name_ref,
+@@ -1563,46 +1510,51 @@
+                                CFStringGetSystemEncoding());
+ 
+             stats_dict = (CFDictionaryRef)CFDictionaryGetValue(
+-                                    props_dict,
+-                                    CFSTR(kIOBlockStorageDriverStatisticsKey));
++                props_dict, CFSTR(kIOBlockStorageDriverStatisticsKey));
+ 
+             if (stats_dict == NULL) {
+-                PyErr_SetString(PyExc_RuntimeError, "Unable to get disk stats.");
++                PyErr_SetString(PyExc_RuntimeError,
++                                "Unable to get disk stats.");
+                 goto error;
+             }
+ 
+             CFNumberRef number;
+-            int64_t reads, writes, read_bytes, write_bytes, read_time, write_time = 0;
++            int64_t reads = 0;
++            int64_t writes = 0;
++            int64_t read_bytes = 0;
++            int64_t write_bytes = 0;
++            int64_t read_time = 0;
++            int64_t write_time = 0;
+ 
+-            /* Get disk reads/writes */
++            // Get disk reads/writes
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+-                            stats_dict,
+-                            CFSTR(kIOBlockStorageDriverStatisticsReadsKey))))
++                    stats_dict,
++                    CFSTR(kIOBlockStorageDriverStatisticsReadsKey))))
+             {
+                 CFNumberGetValue(number, kCFNumberSInt64Type, &reads);
+             }
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+-                            stats_dict,
+-                            CFSTR(kIOBlockStorageDriverStatisticsWritesKey))))
++                    stats_dict,
++                    CFSTR(kIOBlockStorageDriverStatisticsWritesKey))))
+             {
+                 CFNumberGetValue(number, kCFNumberSInt64Type, &writes);
+             }
+ 
+-            /* Get disk bytes read/written */
++            // Get disk bytes read/written
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+-                        stats_dict,
+-                        CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey))))
++                    stats_dict,
++                    CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey))))
+             {
+                 CFNumberGetValue(number, kCFNumberSInt64Type, &read_bytes);
+             }
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+-                stats_dict,
+-                CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey))))
++                    stats_dict,
++                    CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey))))
+             {
+                 CFNumberGetValue(number, kCFNumberSInt64Type, &write_bytes);
+             }
+ 
+-            /* Get disk time spent reading/writing (nanoseconds) */
++            // Get disk time spent reading/writing (nanoseconds)
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+                     stats_dict,
+                     CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey))))
+@@ -1611,18 +1563,22 @@
+             }
+             if ((number = (CFNumberRef)CFDictionaryGetValue(
+                     stats_dict,
+-                    CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)))) {
++                    CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey))))
++            {
+                 CFNumberGetValue(number, kCFNumberSInt64Type, &write_time);
+             }
+ 
+             // Read/Write time on OS X comes back in nanoseconds and in psutil
+             // we've standardized on milliseconds so do the conversion.
+-            py_disk_info = Py_BuildValue("(KKKKKK)",
+-                reads, writes,
+-                read_bytes, write_bytes,
+-                read_time / 1000 / 1000, write_time / 1000 / 1000
+-            );
+-            if (!py_disk_info)
++            py_disk_info = Py_BuildValue(
++                "(KKKKKK)",
++                reads,
++                writes,
++                read_bytes,
++                write_bytes,
++                read_time / 1000 / 1000,
++                write_time / 1000 / 1000);
++           if (!py_disk_info)
+                 goto error;
+             if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
+                 goto error;
+@@ -1649,8 +1605,8 @@
+ /*
+  * Return currently connected users as a list of tuples.
+  */
+-static PyObject*
+-get_system_users(PyObject* self, PyObject* args)
++static PyObject *
++psutil_users(PyObject *self, PyObject *args)
+ {
+     struct utmpx *utx;
+     PyObject *ret_list = PyList_New(0);
+@@ -1661,7 +1617,8 @@
+     while ((utx = getutxent()) != NULL) {
+         if (utx->ut_type != USER_PROCESS)
+             continue;
+-        tuple = Py_BuildValue("(sssf)",
++        tuple = Py_BuildValue(
++            "(sssf)",
+             utx->ut_user,             // username
+             utx->ut_line,             // tty
+             utx->ut_host,             // hostname
+@@ -1694,75 +1651,77 @@
+ static PyMethodDef
+ PsutilMethods[] =
+ {
+-     // --- per-process functions
++    // --- per-process functions
+ 
+-     {"get_process_name", get_process_name, METH_VARARGS,
+-        "Return process name"},
+-     {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
+-        "Return process cmdline as a list of cmdline arguments"},
+-     {"get_process_exe", get_process_exe, METH_VARARGS,
+-        "Return path of the process executable"},
+-     {"get_process_cwd", get_process_cwd, METH_VARARGS,
+-        "Return process current working directory."},
+-     {"get_process_ppid", get_process_ppid, METH_VARARGS,
+-        "Return process ppid as an integer"},
+-     {"get_process_uids", get_process_uids, METH_VARARGS,
+-        "Return process real user id as an integer"},
+-     {"get_process_gids", get_process_gids, METH_VARARGS,
+-        "Return process real group id as an integer"},
+-     {"get_process_cpu_times", get_process_cpu_times, METH_VARARGS,
+-           "Return tuple of user/kern time for the given PID"},
+-     {"get_process_create_time", get_process_create_time, METH_VARARGS,
+-         "Return a float indicating the process create time expressed in "
+-         "seconds since the epoch"},
+-     {"get_process_memory_info", get_process_memory_info, METH_VARARGS,
+-         "Return memory information about a process"},
+-     {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
+-         "Return number of threads used by process"},
+-     {"get_process_status", get_process_status, METH_VARARGS,
+-         "Return process status as an integer"},
+-     {"get_process_threads", get_process_threads, METH_VARARGS,
+-         "Return process threads as a list of tuples"},
+-     {"get_process_open_files", get_process_open_files, METH_VARARGS,
+-         "Return files opened by process as a list of tuples"},
+-     {"get_process_num_fds", get_process_num_fds, METH_VARARGS,
+-         "Return the number of fds opened by process."},
+-     {"get_process_num_ctx_switches", get_process_num_ctx_switches, METH_VARARGS,
+-         "Return the number of context switches performed by process"},
+-     {"get_process_connections", get_process_connections, METH_VARARGS,
+-         "Get process TCP and UDP connections as a list of tuples"},
+-     {"get_process_tty_nr", get_process_tty_nr, METH_VARARGS,
+-         "Return process tty number as an integer"},
+-     {"get_process_memory_maps", get_process_memory_maps, METH_VARARGS,
+-         "Return a list of tuples for every process's memory map"},
+-
+-     // --- system-related functions
+-
+-     {"get_pid_list", get_pid_list, METH_VARARGS,
+-         "Returns a list of PIDs currently running on the system"},
+-     {"get_num_cpus", get_num_cpus, METH_VARARGS,
+-           "Return number of CPUs on the system"},
+-     {"get_virtual_mem", get_virtual_mem, METH_VARARGS,
+-         "Return system virtual memory stats"},
+-     {"get_swap_mem", get_swap_mem, METH_VARARGS,
+-         "Return stats about swap memory, in bytes"},
+-     {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
+-         "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
+-     {"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS,
+-         "Return system per-cpu times as a list of tuples"},
+-     {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
+-         "Return the system boot time expressed in seconds since the epoch."},
+-     {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
+-         "Return a list of tuples including device, mount point and "
+-         "fs type for all partitions mounted on the system."},
+-     {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
+-         "Return dict of tuples of networks I/O information."},
+-     {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
+-         "Return dict of tuples of disks I/O information."},
+-     {"get_system_users", get_system_users, METH_VARARGS,
+-        "Return currently connected users as a list of tuples"},
++    {"proc_name", psutil_proc_name, METH_VARARGS,
++     "Return process name"},
++    {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
++     "Return process cmdline as a list of cmdline arguments"},
++    {"proc_exe", psutil_proc_exe, METH_VARARGS,
++     "Return path of the process executable"},
++    {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
++     "Return process current working directory."},
++    {"proc_ppid", psutil_proc_ppid, METH_VARARGS,
++     "Return process ppid as an integer"},
++    {"proc_uids", psutil_proc_uids, METH_VARARGS,
++     "Return process real user id as an integer"},
++    {"proc_gids", psutil_proc_gids, METH_VARARGS,
++     "Return process real group id as an integer"},
++    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
++     "Return tuple of user/kern time for the given PID"},
++    {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
++     "Return a float indicating the process create time expressed in "
++     "seconds since the epoch"},
++    {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
++     "Return memory information about a process"},
++    {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS,
++     "Return number of threads used by process"},
++    {"proc_status", psutil_proc_status, METH_VARARGS,
++     "Return process status as an integer"},
++    {"proc_threads", psutil_proc_threads, METH_VARARGS,
++     "Return process threads as a list of tuples"},
++    {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
++     "Return files opened by process as a list of tuples"},
++    {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS,
++     "Return the number of fds opened by process."},
++    {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
++     "Return the number of context switches performed by process"},
++    {"proc_connections", psutil_proc_connections, METH_VARARGS,
++     "Get process TCP and UDP connections as a list of tuples"},
++    {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS,
++     "Return process tty number as an integer"},
++    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
++     "Return a list of tuples for every process's memory map"},
++
++    // --- system-related functions
++
++    {"pids", psutil_pids, METH_VARARGS,
++     "Returns a list of PIDs currently running on the system"},
++    {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
++     "Return number of logical CPUs on the system"},
++    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
++     "Return number of physical CPUs on the system"},
++    {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
++     "Return system virtual memory stats"},
++    {"swap_mem", psutil_swap_mem, METH_VARARGS,
++     "Return stats about swap memory, in bytes"},
++    {"cpu_times", psutil_cpu_times, METH_VARARGS,
++     "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
++    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
++     "Return system per-cpu times as a list of tuples"},
++    {"boot_time", psutil_boot_time, METH_VARARGS,
++     "Return the system boot time expressed in seconds since the epoch."},
++    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
++     "Return a list of tuples including device, mount point and "
++     "fs type for all partitions mounted on the system."},
++    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
++     "Return dict of tuples of networks I/O information."},
++    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
++     "Return dict of tuples of disks I/O information."},
++    {"users", psutil_users, METH_VARARGS,
++     "Return currently connected users as a list of tuples"},
+ 
+-     {NULL, NULL, 0, NULL}
++    {NULL, NULL, 0, NULL}
+ };
+ 
+ 
+@@ -1791,8 +1750,7 @@
+ }
+ 
+ 
+-static struct PyModuleDef
+-moduledef = {
++static struct PyModuleDef moduledef = {
+     PyModuleDef_HEAD_INIT,
+     "psutil_osx",
+     NULL,
+@@ -1806,8 +1764,7 @@
+ 
+ #define INITERROR return NULL
+ 
+-PyObject *
+-PyInit__psutil_osx(void)
++PyMODINIT_FUNC PyInit__psutil_osx(void)
+ 
+ #else
+ #define INITERROR return
+@@ -1821,6 +1778,7 @@
+ #else
+     PyObject *module = Py_InitModule("_psutil_osx", PsutilMethods);
+ #endif
++    PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
+     // process status constants, defined in:
+     // http://fxr.watson.org/fxr/source/bsd/sys/proc.h?v=xnu-792.6.70#L149
+     PyModule_AddIntConstant(module, "SIDL", SIDL);
+@@ -1828,10 +1786,22 @@
+     PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+     PyModule_AddIntConstant(module, "SSTOP", SSTOP);
+     PyModule_AddIntConstant(module, "SZOMB", SZOMB);
++    // connection status constants
++    PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
++    PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
++    PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
++    PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
++    PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
++    PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
++    PyModule_AddIntConstant(module, "TCPS_SYN_RECEIVED", TCPS_SYN_RECEIVED);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
++    PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
++    PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
++    PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
+ 
+-    if (module == NULL) {
++    if (module == NULL)
+         INITERROR;
+-    }
+ #if PY_MAJOR_VERSION >= 3
+     return module;
+ #endif
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_osx.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_osx.h	2015-06-17 19:33:33.000000000 -0700
+@@ -2,41 +2,40 @@
+  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * OS X platform-specific module methods for _psutil_osx
+  */
+ 
+ #include <Python.h>
+ 
+ // --- per-process functions
+-static PyObject* get_process_name(PyObject* self, PyObject* args);
+-static PyObject* get_process_cmdline(PyObject* self, PyObject* args);
+-static PyObject* get_process_cwd(PyObject* self, PyObject* args);
+-static PyObject* get_process_exe(PyObject* self, PyObject* args);
+-static PyObject* get_process_ppid(PyObject* self, PyObject* args);
+-static PyObject* get_process_uids(PyObject* self, PyObject* args);
+-static PyObject* get_process_gids(PyObject* self, PyObject* args);
+-static PyObject* get_process_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* get_process_create_time(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_info(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_status(PyObject* self, PyObject* args);
+-static PyObject* get_process_threads(PyObject* self, PyObject* args);
+-static PyObject* get_process_open_files(PyObject* self, PyObject* args);
+-static PyObject* get_process_connections(PyObject* self, PyObject* args);
+-static PyObject* get_process_num_fds(PyObject* self, PyObject* args);
+-static PyObject* get_process_tty_nr(PyObject* self, PyObject* args);
+-static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_connections(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_gids(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_ppid(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_status(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_tty_nr(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_uids(PyObject* self, PyObject* args);
+ 
+ // --- system-related functions
+-static PyObject* get_pid_list(PyObject* self, PyObject* args);
+-static PyObject* get_num_cpus(PyObject* self, PyObject* args);
+-static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
+-static PyObject* get_swap_mem(PyObject* self, PyObject* args);
+-static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* get_system_per_cpu_times(PyObject* self, PyObject* args);
+-static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
+-static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
+-static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
+-static PyObject* get_system_users(PyObject* self, PyObject* args);
++static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
++static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_pids(PyObject* self, PyObject* args);
++static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
++static PyObject* psutil_users(PyObject* self, PyObject* args);
++static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_posix.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_posix.c	2015-06-17 19:33:33.000000000 -0700
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+@@ -10,6 +10,24 @@
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/resource.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <ifaddrs.h>
++
++#ifdef __linux
++#include <netdb.h>
++#include <linux/if_packet.h>
++#endif  // end linux
++
++#if defined(__FreeBSD__) || defined(__APPLE__)
++#include <netdb.h>
++#include <netinet/in.h>
++#include <net/if_dl.h>
++#endif
++
++#if defined(__sun)
++#include <netdb.h>
++#endif
+ 
+ #include "_psutil_posix.h"
+ 
+@@ -17,54 +35,436 @@
+ /*
+  * Given a PID return process priority as a Python integer.
+  */
+-static PyObject*
+-posix_getpriority(PyObject* self, PyObject* args)
++static PyObject *
++psutil_posix_getpriority(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int priority;
+     errno = 0;
+-    if (! PyArg_ParseTuple(args, "l", &pid)) {
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
+         return NULL;
+-    }
+     priority = getpriority(PRIO_PROCESS, pid);
+-    if (errno != 0) {
++    if (errno != 0)
+         return PyErr_SetFromErrno(PyExc_OSError);
+-    }
+     return Py_BuildValue("i", priority);
+ }
+ 
++
+ /*
+  * Given a PID and a value change process priority.
+  */
+-static PyObject*
+-posix_setpriority(PyObject* self, PyObject* args)
++static PyObject *
++psutil_posix_setpriority(PyObject *self, PyObject *args)
+ {
+     long pid;
+     int priority;
+     int retval;
+-    if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
++
++    if (! PyArg_ParseTuple(args, "li", &pid, &priority))
+         return NULL;
+-    }
+     retval = setpriority(PRIO_PROCESS, pid, priority);
+-    if (retval == -1) {
++    if (retval == -1)
+         return PyErr_SetFromErrno(PyExc_OSError);
++    Py_RETURN_NONE;
++}
++
++
++/*
++ * Translate a sockaddr struct into a Python string.
++ * Return None if address family is not AF_INET* or AF_PACKET.
++ */
++static PyObject *
++psutil_convert_ipaddr(struct sockaddr *addr, int family)
++{
++    char buf[NI_MAXHOST];
++    int err;
++    int addrlen;
++    int n;
++    size_t len;
++    const char *data;
++    char *ptr;
++
++    if (addr == NULL) {
++        Py_INCREF(Py_None);
++        return Py_None;
++    }
++    else if (family == AF_INET || family == AF_INET6) {
++        if (family == AF_INET)
++            addrlen = sizeof(struct sockaddr_in);
++        else
++            addrlen = sizeof(struct sockaddr_in6);
++        err = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
++                          NI_NUMERICHOST);
++        if (err != 0) {
++            // XXX we get here on FreeBSD when processing 'lo' / AF_INET6
++            // broadcast. Not sure what to do other than returning None.
++            // ifconfig does not show anything BTW.
++            //PyErr_Format(PyExc_RuntimeError, gai_strerror(err));
++            //return NULL;
++            Py_INCREF(Py_None);
++            return Py_None;
++        }
++        else {
++            return Py_BuildValue("s", buf);
++        }
++    }
++#ifdef __linux
++    else if (family == AF_PACKET) {
++        struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
++        len = lladdr->sll_halen;
++        data = (const char *)lladdr->sll_addr;
++    }
++#endif
++#if defined(__FreeBSD__) || defined(__APPLE__)
++    else if (addr->sa_family == AF_LINK) {
++        // Note: prior to Python 3.4 socket module does not expose
++        // AF_LINK so we'll do.
++        struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
++        len = dladdr->sdl_alen;
++        data = LLADDR(dladdr);
++    }
++#endif
++    else {
++        // unknown family
++        Py_INCREF(Py_None);
++        return Py_None;
++    }
++
++    // AF_PACKET or AF_LINK
++    if (len > 0) {
++        ptr = buf;
++        for (n = 0; n < len; ++n) {
++            sprintf(ptr, "%02x:", data[n] & 0xff);
++            ptr += 3;
++        }
++        *--ptr = '\0';
++        return Py_BuildValue("s", buf);
++    }
++    else {
++        Py_INCREF(Py_None);
++        return Py_None;
++    }
++}
++
++
++/*
++ * Return NICs information a-la ifconfig as a list of tuples.
++ * TODO: on Solaris we won't get any MAC address.
++ */
++static PyObject*
++psutil_net_if_addrs(PyObject* self, PyObject* args)
++{
++    struct ifaddrs *ifaddr, *ifa;
++    int family;
++
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++    PyObject *py_address = NULL;
++    PyObject *py_netmask = NULL;
++    PyObject *py_broadcast = NULL;
++
++    if (py_retlist == NULL)
++        return NULL;
++    if (getifaddrs(&ifaddr) == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
++        if (!ifa->ifa_addr)
++            continue;
++        family = ifa->ifa_addr->sa_family;
++        py_address = psutil_convert_ipaddr(ifa->ifa_addr, family);
++        // If the primary address can't be determined just skip it.
++        // I've never seen this happen on Linux but I did on FreeBSD.
++        if (py_address == Py_None)
++            continue;
++        if (py_address == NULL)
++            goto error;
++        py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family);
++        if (py_netmask == NULL)
++            goto error;
++#ifdef __linux
++        py_broadcast = psutil_convert_ipaddr(ifa->ifa_ifu.ifu_broadaddr, family);
++#else
++        py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
++#endif
++        if (py_broadcast == NULL)
++            goto error;
++        py_tuple = Py_BuildValue(
++            "(siOOO)",
++            ifa->ifa_name,
++            family,
++            py_address,
++            py_netmask,
++            py_broadcast
++        );
++
++        if (! py_tuple)
++            goto error;
++        if (PyList_Append(py_retlist, py_tuple))
++            goto error;
++        Py_DECREF(py_tuple);
++        Py_DECREF(py_address);
++        Py_DECREF(py_netmask);
++        Py_DECREF(py_broadcast);
++    }
++
++    freeifaddrs(ifaddr);
++    return py_retlist;
++
++error:
++    if (ifaddr != NULL)
++        freeifaddrs(ifaddr);
++    Py_DECREF(py_retlist);
++    Py_XDECREF(py_tuple);
++    Py_XDECREF(py_address);
++    Py_XDECREF(py_netmask);
++    Py_XDECREF(py_broadcast);
++    return NULL;
++}
++
++
++/*
++ * net_if_stats() implementation. This is here because it is common
++ * to both OSX and FreeBSD and I didn't know where else to put it.
++ */
++#if defined(__FreeBSD__) || defined(__APPLE__)
++
++#include <sys/sockio.h>
++#include <net/if_media.h>
++#include <net/if.h>
++
++int psutil_get_nic_speed(int ifm_active) {
++    // Determine NIC speed. Taken from:
++    // http://www.i-scream.org/libstatgrab/
++    // Assuming only ETHER devices
++    switch(IFM_TYPE(ifm_active)) {
++        case IFM_ETHER:
++            switch(IFM_SUBTYPE(ifm_active)) {
++#if defined(IFM_HPNA_1) && ((!defined(IFM_10G_LR)) \
++    || (IFM_10G_LR != IFM_HPNA_1))
++                // HomePNA 1.0 (1Mb/s)
++                case(IFM_HPNA_1):
++                    return 1;
++#endif
++                // 10 Mbit
++                case(IFM_10_T):  // 10BaseT - RJ45
++                case(IFM_10_2):  // 10Base2 - Thinnet
++                case(IFM_10_5):  // 10Base5 - AUI
++                case(IFM_10_STP):  // 10BaseT over shielded TP
++                case(IFM_10_FL):  // 10baseFL - Fiber
++                    return 10;
++                // 100 Mbit
++                case(IFM_100_TX):  // 100BaseTX - RJ45
++                case(IFM_100_FX):  // 100BaseFX - Fiber
++                case(IFM_100_T4):  // 100BaseT4 - 4 pair cat 3
++                case(IFM_100_VG):  // 100VG-AnyLAN
++                case(IFM_100_T2):  // 100BaseT2
++                    return 100;
++                // 1000 Mbit
++                case(IFM_1000_SX):  // 1000BaseSX - multi-mode fiber
++                case(IFM_1000_LX):  // 1000baseLX - single-mode fiber
++                case(IFM_1000_CX):  // 1000baseCX - 150ohm STP
++#if defined(IFM_1000_TX) && !defined(OPENBSD)
++                // FreeBSD 4 and others (but NOT OpenBSD)?
++                case(IFM_1000_TX):
++#endif
++#ifdef IFM_1000_FX
++                case(IFM_1000_FX):
++#endif
++#ifdef IFM_1000_T
++                case(IFM_1000_T):
++#endif
++                    return 1000;
++#if defined(IFM_10G_SR) || defined(IFM_10G_LR) || defined(IFM_10G_CX4) \
++         || defined(IFM_10G_T)
++#ifdef IFM_10G_SR
++                case(IFM_10G_SR):
++#endif
++#ifdef IFM_10G_LR
++                case(IFM_10G_LR):
++#endif
++#ifdef IFM_10G_CX4
++                case(IFM_10G_CX4):
++#endif
++#ifdef IFM_10G_TWINAX
++                case(IFM_10G_TWINAX):
++#endif
++#ifdef IFM_10G_TWINAX_LONG
++                case(IFM_10G_TWINAX_LONG):
++#endif
++#ifdef IFM_10G_T
++                case(IFM_10G_T):
++#endif
++                    return 10000;
++#endif
++#if defined(IFM_2500_SX)
++#ifdef IFM_2500_SX
++                case(IFM_2500_SX):
++#endif
++                    return 2500;
++#endif // any 2.5GBit stuff...
++                // We don't know what it is
++                default:
++                    return 0;
++            }
++            break;
++
++#ifdef IFM_TOKEN
++        case IFM_TOKEN:
++            switch(IFM_SUBTYPE(ifm_active)) {
++                case IFM_TOK_STP4:  // Shielded twisted pair 4m - DB9
++                case IFM_TOK_UTP4:  // Unshielded twisted pair 4m - RJ45
++                    return 4;
++                case IFM_TOK_STP16:  // Shielded twisted pair 16m - DB9
++                case IFM_TOK_UTP16:  // Unshielded twisted pair 16m - RJ45
++                    return 16;
++#if defined(IFM_TOK_STP100) || defined(IFM_TOK_UTP100)
++#ifdef IFM_TOK_STP100
++                case IFM_TOK_STP100:  // Shielded twisted pair 100m - DB9
++#endif
++#ifdef IFM_TOK_UTP100
++                case IFM_TOK_UTP100:  // Unshielded twisted pair 100m - RJ45
++#endif
++                    return 100;
++#endif
++                // We don't know what it is
++                default:
++                    return 0;
++            }
++            break;
++#endif
++
++#ifdef IFM_FDDI
++        case IFM_FDDI:
++            switch(IFM_SUBTYPE(ifm_active)) {
++                // We don't know what it is
++                default:
++                    return 0;
++            }
++            break;
++#endif
++        case IFM_IEEE80211:
++            switch(IFM_SUBTYPE(ifm_active)) {
++                case IFM_IEEE80211_FH1:  // Frequency Hopping 1Mbps
++                case IFM_IEEE80211_DS1:  // Direct Sequence 1Mbps
++                    return 1;
++                case IFM_IEEE80211_FH2:  // Frequency Hopping 2Mbps
++                case IFM_IEEE80211_DS2:  // Direct Sequence 2Mbps
++                    return 2;
++                case IFM_IEEE80211_DS5:  // Direct Sequence 5Mbps
++                    return 5;
++                case IFM_IEEE80211_DS11:  // Direct Sequence 11Mbps
++                    return 11;
++                case IFM_IEEE80211_DS22:  // Direct Sequence 22Mbps
++                    return 22;
++                // We don't know what it is
++                default:
++                    return 0;
++            }
++            break;
++
++        default:
++            return 0;
+     }
+-    Py_INCREF(Py_None);
+-    return Py_None;
+ }
+ 
+ 
+ /*
++ * Return stats about a particular network interface.
++ * References:
++ * http://www.i-scream.org/libstatgrab/
++ */
++static PyObject *
++psutil_net_if_stats(PyObject *self, PyObject *args)
++{
++    char *nic_name;
++    int sock = 0;
++    int ret;
++    int duplex;
++    int speed;
++    int mtu;
++    struct ifreq ifr;
++    struct ifmediareq ifmed;
++
++    PyObject *py_is_up = NULL;
++
++    if (! PyArg_ParseTuple(args, "s", &nic_name))
++        return NULL;
++
++    sock = socket(AF_INET, SOCK_DGRAM, 0);
++    if (sock == -1)
++        goto error;
++    strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
++
++    // is up?
++    ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
++    if (ret == -1)
++        goto error;
++    if ((ifr.ifr_flags & IFF_UP) != 0)
++        py_is_up = Py_True;
++    else
++        py_is_up = Py_False;
++    Py_INCREF(py_is_up);
++
++    // MTU
++    ret = ioctl(sock, SIOCGIFMTU, &ifr);
++    if (ret == -1)
++        goto error;
++    mtu = ifr.ifr_mtu;
++
++    // speed / duplex
++    memset(&ifmed, 0, sizeof(struct ifmediareq));
++    strlcpy(ifmed.ifm_name, nic_name, sizeof(ifmed.ifm_name));
++    ret = ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmed);
++    if (ret == -1) {
++        speed = 0;
++        duplex = 0;
++    }
++    else {
++        speed = psutil_get_nic_speed(ifmed.ifm_active);
++        if ((ifmed.ifm_active | IFM_FDX) == ifmed.ifm_active)
++            duplex = 2;
++        else if ((ifmed.ifm_active | IFM_HDX) == ifmed.ifm_active)
++            duplex = 1;
++        else
++            duplex = 0;
++    }
++
++    close(sock);
++    Py_DECREF(py_is_up);
++
++    return Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu);
++
++error:
++    Py_XDECREF(py_is_up);
++    if (sock != 0)
++        close(sock);
++    PyErr_SetFromErrno(PyExc_OSError);
++    return NULL;
++}
++#endif  // net_if_stats() implementation
++
++
++/*
+  * define the psutil C module methods and initialize the module.
+  */
+ static PyMethodDef
+ PsutilMethods[] =
+ {
+-     {"getpriority", posix_getpriority, METH_VARARGS,
+-        "Return process priority"},
+-     {"setpriority", posix_setpriority, METH_VARARGS,
+-        "Set process priority"},
+-     {NULL, NULL, 0, NULL}
++    {"getpriority", psutil_posix_getpriority, METH_VARARGS,
++     "Return process priority"},
++    {"setpriority", psutil_posix_setpriority, METH_VARARGS,
++     "Set process priority"},
++    {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
++     "Retrieve NICs information"},
++#if defined(__FreeBSD__) || defined(__APPLE__)
++    {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
++     "Return NIC stats."},
++#endif
++    {NULL, NULL, 0, NULL}
+ };
+ 
+ struct module_state {
+@@ -91,23 +491,21 @@
+     return 0;
+ }
+ 
+-static struct PyModuleDef
+-moduledef = {
+-        PyModuleDef_HEAD_INIT,
+-        "psutil_posix",
+-        NULL,
+-        sizeof(struct module_state),
+-        PsutilMethods,
+-        NULL,
+-        psutil_posix_traverse,
+-        psutil_posix_clear,
+-        NULL
++static struct PyModuleDef moduledef = {
++    PyModuleDef_HEAD_INIT,
++    "psutil_posix",
++    NULL,
++    sizeof(struct module_state),
++    PsutilMethods,
++    NULL,
++    psutil_posix_traverse,
++    psutil_posix_clear,
++    NULL
+ };
+ 
+ #define INITERROR return NULL
+ 
+-PyObject *
+-PyInit__psutil_posix(void)
++PyMODINIT_FUNC PyInit__psutil_posix(void)
+ 
+ #else
+ #define INITERROR return
+@@ -120,13 +518,14 @@
+ #else
+     PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods);
+ #endif
+-    if (module == NULL) {
++
++#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__sun)
++    PyModule_AddIntConstant(module, "AF_LINK", AF_LINK);
++#endif
++
++    if (module == NULL)
+         INITERROR;
+-    }
+ #if PY_MAJOR_VERSION >= 3
+     return module;
+ #endif
+ }
+-
+-
+-
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_posix.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_posix.h	2015-06-17 19:33:33.000000000 -0700
+@@ -1,12 +1,15 @@
+ /*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * POSIX specific module methods for _psutil_posix
+  */
+ 
+ #include <Python.h>
+ 
+-static PyObject* posix_getpriority(PyObject* self, PyObject* args);
+-static PyObject* posix_setpriority(PyObject* self, PyObject* args);
++static PyObject* psutil_net_if_addrs(PyObject* self, PyObject* args);
++static PyObject* psutil_posix_getpriority(PyObject* self, PyObject* args);
++static PyObject* psutil_posix_setpriority(PyObject* self, PyObject* args);
++
++#if defined(__FreeBSD__) || defined(__APPLE__)
++static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
++#endif
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_sunos.c	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_sunos.c	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,1389 @@
++/*
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ * Functions specific to Sun OS Solaris platforms.
++ *
++ * Thanks to Justin Venus who originally wrote a consistent part of
++ * this in Cython which I later on translated in C.
++ */
++
++
++#include <Python.h>
++
++// fix for "Cannot use procfs in the large file compilation environment"
++// error, see:
++// http://sourceware.org/ml/gdb-patches/2010-11/msg00336.html
++#undef _FILE_OFFSET_BITS
++#define _STRUCTURED_PROC 1
++
++// fix compilation issue on SunOS 5.10, see:
++// https://github.com/giampaolo/psutil/issues/421
++#define NEW_MIB_COMPLIANT
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/proc.h>
++#include <sys/swap.h>
++#include <sys/sysinfo.h>
++#include <sys/mntent.h>  // for MNTTAB
++#include <sys/mnttab.h>
++#include <sys/procfs.h>
++#include <sys/sockio.h>
++#include <sys/socket.h>
++#include <fcntl.h>
++#include <utmpx.h>
++#include <kstat.h>
++#include <sys/ioctl.h>
++#include <sys/tihdr.h>
++#include <stropts.h>
++#include <inet/tcp.h>
++#include <arpa/inet.h>
++#include <net/if.h>
++
++#include "_psutil_sunos.h"
++
++
++#define TV2DOUBLE(t)   (((t).tv_nsec * 0.000000001) + (t).tv_sec)
++
++/*
++ * Read a file content and fills a C structure with it.
++ */
++int
++psutil_file_to_struct(char *path, void *fstruct, size_t size)
++{
++    int fd;
++    size_t nbytes;
++    fd = open(path, O_RDONLY);
++    if (fd == -1) {
++        PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
++        return 0;
++    }
++    nbytes = read(fd, fstruct, size);
++    if (nbytes <= 0) {
++        close(fd);
++        PyErr_SetFromErrno(PyExc_OSError);
++        return 0;
++    }
++    if (nbytes != size) {
++        close(fd);
++        PyErr_SetString(PyExc_RuntimeError, "structure size mismatch");
++        return 0;
++    }
++    close(fd);
++    return nbytes;
++}
++
++
++/*
++ * Return process ppid, rss, vms, ctime, nice, nthreads, status and tty
++ * as a Python tuple.
++ */
++static PyObject *
++psutil_proc_basic_info(PyObject *self, PyObject *args)
++{
++    int pid;
++    char path[100];
++    psinfo_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/psinfo", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    return Py_BuildValue("ikkdiiik",
++                         info.pr_ppid,              // parent pid
++                         info.pr_rssize,            // rss
++                         info.pr_size,              // vms
++                         TV2DOUBLE(info.pr_start),  // create time
++                         info.pr_lwp.pr_nice,       // nice
++                         info.pr_nlwp,              // no. of threads
++                         info.pr_lwp.pr_state,      // status code
++                         info.pr_ttydev             // tty nr
++                        );
++}
++
++
++/*
++ * Return process name and args as a Python tuple.
++ */
++static PyObject *
++psutil_proc_name_and_args(PyObject *self, PyObject *args)
++{
++    int pid;
++    char path[100];
++    psinfo_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/psinfo", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    return Py_BuildValue("ss", info.pr_fname, info.pr_psargs);
++}
++
++
++/*
++ * Return process user and system CPU times as a Python tuple.
++ */
++static PyObject *
++psutil_proc_cpu_times(PyObject *self, PyObject *args)
++{
++    int pid;
++    char path[100];
++    pstatus_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/status", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    // results are more precise than os.times()
++    return Py_BuildValue("dd",
++                         TV2DOUBLE(info.pr_utime),
++                         TV2DOUBLE(info.pr_stime));
++}
++
++
++/*
++ * Return process uids/gids as a Python tuple.
++ */
++static PyObject *
++psutil_proc_cred(PyObject *self, PyObject *args)
++{
++    int pid;
++    char path[100];
++    prcred_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/cred", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    return Py_BuildValue("iiiiii",
++                         info.pr_ruid, info.pr_euid, info.pr_suid,
++                         info.pr_rgid, info.pr_egid, info.pr_sgid);
++}
++
++
++/*
++ * Return process uids/gids as a Python tuple.
++ */
++static PyObject *
++psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
++{
++    int pid;
++    char path[100];
++    prusage_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/usage", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    return Py_BuildValue("kk", info.pr_vctx, info.pr_ictx);
++}
++
++
++/*
++ * Process IO counters.
++ *
++ * Commented out and left here as a reminder.  Apparently we cannot
++ * retrieve process IO stats because:
++ * - 'pr_ioch' is a sum of chars read and written, with no distinction
++ * - 'pr_inblk' and 'pr_oublk', which should be the number of bytes
++ *    read and written, hardly increase and according to:
++ *    http://www.brendangregg.com/Perf/paper_diskubyp1.pdf
++ *    ...they should be meaningless anyway.
++ *
++static PyObject*
++proc_io_counters(PyObject* self, PyObject* args)
++{
++    int pid;
++    char path[100];
++    prusage_t info;
++
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        return NULL;
++    sprintf(path, "/proc/%i/usage", pid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++
++    // On Solaris we only have 'pr_ioch' which accounts for bytes read
++    // *and* written.
++    // 'pr_inblk' and 'pr_oublk' should be expressed in blocks of
++    // 8KB according to:
++    // http://www.brendangregg.com/Perf/paper_diskubyp1.pdf  (pag. 8)
++    return Py_BuildValue("kkkk",
++                         info.pr_ioch,
++                         info.pr_ioch,
++                         info.pr_inblk,
++                         info.pr_oublk);
++}
++ */
++
++
++/*
++ * Return information about a given process thread.
++ */
++static PyObject *
++psutil_proc_query_thread(PyObject *self, PyObject *args)
++{
++    int pid, tid;
++    char path[100];
++    lwpstatus_t info;
++
++    if (! PyArg_ParseTuple(args, "ii", &pid, &tid))
++        return NULL;
++    sprintf(path, "/proc/%i/lwp/%i/lwpstatus", pid, tid);
++    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
++        return NULL;
++    return Py_BuildValue("dd",
++                         TV2DOUBLE(info.pr_utime),
++                         TV2DOUBLE(info.pr_stime));
++}
++
++
++/*
++ * Return information about system virtual memory.
++ */
++static PyObject *
++psutil_swap_mem(PyObject *self, PyObject *args)
++{
++// XXX (arghhh!)
++// total/free swap mem: commented out as for some reason I can't
++// manage to get the same results shown by "swap -l", despite the
++// code below is exactly the same as:
++// http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/
++//    cmd/swap/swap.c
++// We're going to parse "swap -l" output from Python (sigh!)
++
++/*
++    struct swaptable     *st;
++    struct swapent    *swapent;
++    int    i;
++    struct stat64 statbuf;
++    char *path;
++    char fullpath[MAXPATHLEN+1];
++    int    num;
++
++    if ((num = swapctl(SC_GETNSWP, NULL)) == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        return NULL;
++    }
++    if (num == 0) {
++        PyErr_SetString(PyExc_RuntimeError, "no swap devices configured");
++        return NULL;
++    }
++    if ((st = malloc(num * sizeof(swapent_t) + sizeof (int))) == NULL) {
++        PyErr_SetString(PyExc_RuntimeError, "malloc failed");
++        return NULL;
++    }
++    if ((path = malloc(num * MAXPATHLEN)) == NULL) {
++        PyErr_SetString(PyExc_RuntimeError, "malloc failed");
++        return NULL;
++    }
++    swapent = st->swt_ent;
++    for (i = 0; i < num; i++, swapent++) {
++        swapent->ste_path = path;
++        path += MAXPATHLEN;
++    }
++    st->swt_n = num;
++    if ((num = swapctl(SC_LIST, st)) == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        return NULL;
++    }
++
++    swapent = st->swt_ent;
++    long t = 0, f = 0;
++    for (i = 0; i < num; i++, swapent++) {
++        int diskblks_per_page =(int)(sysconf(_SC_PAGESIZE) >> DEV_BSHIFT);
++        t += (long)swapent->ste_pages;
++        f += (long)swapent->ste_free;
++    }
++
++    free(st);
++    return Py_BuildValue("(kk)", t, f);
++*/
++
++    kstat_ctl_t *kc;
++    kstat_t     *k;
++    cpu_stat_t  *cpu;
++    int         cpu_count = 0;
++    int         flag = 0;
++    uint_t      sin = 0;
++    uint_t      sout = 0;
++
++    kc = kstat_open();
++    if (kc == NULL)
++        return PyErr_SetFromErrno(PyExc_OSError);;
++
++    k = kc->kc_chain;
++    while (k != NULL) {
++        if ((strncmp(k->ks_name, "cpu_stat", 8) == 0) && \
++                (kstat_read(kc, k, NULL) != -1) )
++        {
++            flag = 1;
++            cpu = (cpu_stat_t *) k->ks_data;
++            sin += cpu->cpu_vminfo.pgswapin;    // num pages swapped in
++            sout += cpu->cpu_vminfo.pgswapout;  // num pages swapped out
++        }
++        cpu_count += 1;
++        k = k->ks_next;
++    }
++    kstat_close(kc);
++    if (!flag) {
++        PyErr_SetString(PyExc_RuntimeError, "no swap device was found");
++        return NULL;
++    }
++    return Py_BuildValue("(II)", sin, sout);
++}
++
++
++/*
++ * Return users currently connected on the system.
++ */
++static PyObject *
++psutil_users(PyObject *self, PyObject *args)
++{
++    struct utmpx *ut;
++    PyObject *ret_list = PyList_New(0);
++    PyObject *tuple = NULL;
++    PyObject *user_proc = NULL;
++
++    if (ret_list == NULL)
++        return NULL;
++
++    while (NULL != (ut = getutxent())) {
++        if (ut->ut_type == USER_PROCESS)
++            user_proc = Py_True;
++        else
++            user_proc = Py_False;
++        tuple = Py_BuildValue(
++            "(sssfO)",
++            ut->ut_user,              // username
++            ut->ut_line,              // tty
++            ut->ut_host,              // hostname
++            (float)ut->ut_tv.tv_sec,  // tstamp
++            user_proc);               // (bool) user process
++        if (tuple == NULL)
++            goto error;
++        if (PyList_Append(ret_list, tuple))
++            goto error;
++        Py_DECREF(tuple);
++    }
++    endutent();
++
++    return ret_list;
++
++error:
++    Py_XDECREF(tuple);
++    Py_DECREF(ret_list);
++    if (ut != NULL)
++        endutent();
++    return NULL;
++}
++
++
++/*
++ * Return disk mounted partitions as a list of tuples including device,
++ * mount point and filesystem type.
++ */
++static PyObject *
++psutil_disk_partitions(PyObject *self, PyObject *args)
++{
++    FILE *file;
++    struct mnttab mt;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++
++    if (py_retlist == NULL)
++        return NULL;
++
++    file = fopen(MNTTAB, "rb");
++    if (file == NULL) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    while (getmntent(file, &mt) == 0) {
++        py_tuple = Py_BuildValue(
++            "(ssss)",
++            mt.mnt_special,   // device
++            mt.mnt_mountp,    // mount point
++            mt.mnt_fstype,    // fs type
++            mt.mnt_mntopts);  // options
++        if (py_tuple == NULL)
++            goto error;
++        if (PyList_Append(py_retlist, py_tuple))
++            goto error;
++        Py_DECREF(py_tuple);
++
++    }
++    fclose(file);
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_tuple);
++    Py_DECREF(py_retlist);
++    if (file != NULL)
++        fclose(file);
++    return NULL;
++}
++
++
++/*
++ * Return system-wide CPU times.
++ */
++static PyObject *
++psutil_per_cpu_times(PyObject *self, PyObject *args)
++{
++    kstat_ctl_t *kc;
++    kstat_t *ksp;
++    cpu_stat_t cs;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_cputime = NULL;
++
++    if (py_retlist == NULL)
++        return NULL;
++
++    kc = kstat_open();
++    if (kc == NULL) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
++        if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
++            if (kstat_read(kc, ksp, &cs) == -1) {
++                PyErr_SetFromErrno(PyExc_OSError);
++                goto error;
++            }
++            py_cputime = Py_BuildValue("ffff",
++                                       (float)cs.cpu_sysinfo.cpu[CPU_USER],
++                                       (float)cs.cpu_sysinfo.cpu[CPU_KERNEL],
++                                       (float)cs.cpu_sysinfo.cpu[CPU_IDLE],
++                                       (float)cs.cpu_sysinfo.cpu[CPU_WAIT]);
++            if (py_cputime == NULL)
++                goto error;
++            if (PyList_Append(py_retlist, py_cputime))
++                goto error;
++            Py_DECREF(py_cputime);
++            py_cputime = NULL;
++        }
++    }
++
++    kstat_close(kc);
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_cputime);
++    Py_DECREF(py_retlist);
++    if (kc != NULL)
++        kstat_close(kc);
++    return NULL;
++}
++
++
++/*
++ * Return disk IO statistics.
++ */
++static PyObject *
++psutil_disk_io_counters(PyObject *self, PyObject *args)
++{
++    kstat_ctl_t *kc;
++    kstat_t *ksp;
++    kstat_io_t kio;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_disk_info = NULL;
++
++    if (py_retdict == NULL)
++        return NULL;
++    kc = kstat_open();
++    if (kc == NULL) {
++        PyErr_SetFromErrno(PyExc_OSError);;
++        goto error;
++    }
++    ksp = kc->kc_chain;
++    while (ksp != NULL) {
++        if (ksp->ks_type == KSTAT_TYPE_IO) {
++            if (strcmp(ksp->ks_class, "disk") == 0) {
++                if (kstat_read(kc, ksp, &kio) == -1) {
++                    kstat_close(kc);
++                    return PyErr_SetFromErrno(PyExc_OSError);;
++                }
++                py_disk_info = Py_BuildValue(
++                    "(IIKKLL)",
++                    kio.reads,
++                    kio.writes,
++                    kio.nread,
++                    kio.nwritten,
++                    kio.rtime / 1000 / 1000,  // from nano to milli secs
++                    kio.wtime / 1000 / 1000   // from nano to milli secs
++                );
++                if (!py_disk_info)
++                    goto error;
++                if (PyDict_SetItemString(py_retdict, ksp->ks_name,
++                                         py_disk_info))
++                    goto error;
++                Py_DECREF(py_disk_info);
++            }
++        }
++        ksp = ksp->ks_next;
++    }
++    kstat_close(kc);
++
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_disk_info);
++    Py_DECREF(py_retdict);
++    if (kc != NULL)
++        kstat_close(kc);
++    return NULL;
++}
++
++
++/*
++ * Return process memory mappings.
++ */
++static PyObject *
++psutil_proc_memory_maps(PyObject *self, PyObject *args)
++{
++    int pid;
++    int fd = -1;
++    char path[100];
++    char perms[10];
++    char *name;
++    struct stat st;
++    pstatus_t status;
++
++    prxmap_t *xmap = NULL, *p;
++    off_t size;
++    size_t nread;
++    int nmap;
++    uintptr_t pr_addr_sz;
++    uintptr_t stk_base_sz, brk_base_sz;
++
++    PyObject *pytuple = NULL;
++    PyObject *py_retlist = PyList_New(0);
++
++    if (py_retlist == NULL)
++        return NULL;
++    if (! PyArg_ParseTuple(args, "i", &pid))
++        goto error;
++
++    sprintf(path, "/proc/%i/status", pid);
++    if (! psutil_file_to_struct(path, (void *)&status, sizeof(status)))
++        goto error;
++
++    sprintf(path, "/proc/%i/xmap", pid);
++    if (stat(path, &st) == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    size = st.st_size;
++
++    fd = open(path, O_RDONLY);
++    if (fd == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    xmap = (prxmap_t *)malloc(size);
++    if (xmap == NULL) {
++        PyErr_NoMemory();
++        goto error;
++    }
++
++    nread = pread(fd, xmap, size, 0);
++    nmap = nread / sizeof(prxmap_t);
++    p = xmap;
++
++    while (nmap) {
++        nmap -= 1;
++        if (p == NULL) {
++            p += 1;
++            continue;
++        }
++
++        perms[0] = '\0';
++        pr_addr_sz = p->pr_vaddr + p->pr_size;
++
++        // perms
++        sprintf(perms, "%c%c%c%c%c%c", p->pr_mflags & MA_READ ? 'r' : '-',
++                p->pr_mflags & MA_WRITE ? 'w' : '-',
++                p->pr_mflags & MA_EXEC ? 'x' : '-',
++                p->pr_mflags & MA_SHARED ? 's' : '-',
++                p->pr_mflags & MA_NORESERVE ? 'R' : '-',
++                p->pr_mflags & MA_RESERVED1 ? '*' : ' ');
++
++        // name
++        if (strlen(p->pr_mapname) > 0) {
++            name = p->pr_mapname;
++        }
++        else {
++            if ((p->pr_mflags & MA_ISM) || (p->pr_mflags & MA_SHM)) {
++                name = "[shmid]";
++            }
++            else {
++                stk_base_sz = status.pr_stkbase + status.pr_stksize;
++                brk_base_sz = status.pr_brkbase + status.pr_brksize;
++
++                if ((pr_addr_sz > status.pr_stkbase) &&
++                        (p->pr_vaddr < stk_base_sz)) {
++                    name = "[stack]";
++                }
++                else if ((p->pr_mflags & MA_ANON) && \
++                         (pr_addr_sz > status.pr_brkbase) && \
++                         (p->pr_vaddr < brk_base_sz)) {
++                    name = "[heap]";
++                }
++                else {
++                    name = "[anon]";
++                }
++            }
++        }
++
++        pytuple = Py_BuildValue("iisslll",
++                                p->pr_vaddr,
++                                pr_addr_sz,
++                                perms,
++                                name,
++                                (long)p->pr_rss * p->pr_pagesize,
++                                (long)p->pr_anon * p->pr_pagesize,
++                                (long)p->pr_locked * p->pr_pagesize);
++        if (!pytuple)
++            goto error;
++        if (PyList_Append(py_retlist, pytuple))
++            goto error;
++        Py_DECREF(pytuple);
++
++        // increment pointer
++        p += 1;
++    }
++
++    close(fd);
++    free(xmap);
++    return py_retlist;
++
++error:
++    if (fd != -1)
++        close(fd);
++    Py_XDECREF(pytuple);
++    Py_DECREF(py_retlist);
++    if (xmap != NULL)
++        free(xmap);
++    return NULL;
++}
++
++
++/*
++ * Return a list of tuples for network I/O statistics.
++ */
++static PyObject *
++psutil_net_io_counters(PyObject *self, PyObject *args)
++{
++    kstat_ctl_t    *kc = NULL;
++    kstat_t *ksp;
++    kstat_named_t *rbytes, *wbytes, *rpkts, *wpkts, *ierrs, *oerrs;
++
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_ifc_info = NULL;
++
++    if (py_retdict == NULL)
++        return NULL;
++    kc = kstat_open();
++    if (kc == NULL)
++        goto error;
++
++    ksp = kc->kc_chain;
++    while (ksp != NULL) {
++        if (ksp->ks_type != KSTAT_TYPE_NAMED)
++            goto next;
++        if (strcmp(ksp->ks_class, "net") != 0)
++            goto next;
++        /*
++        // XXX "lo" (localhost) interface makes kstat_data_lookup() fail
++        // (maybe because "ifconfig -a" says it's a virtual interface?).
++        if ((strcmp(ksp->ks_module, "link") != 0) &&
++            (strcmp(ksp->ks_module, "lo") != 0)) {
++            goto skip;
++        */
++        if ((strcmp(ksp->ks_module, "link") != 0))
++            goto next;
++
++        if (kstat_read(kc, ksp, NULL) == -1) {
++            errno = 0;
++            continue;
++        }
++
++        rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes");
++        wbytes = (kstat_named_t *)kstat_data_lookup(ksp, "obytes");
++        rpkts = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets");
++        wpkts = (kstat_named_t *)kstat_data_lookup(ksp, "opackets");
++        ierrs = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors");
++        oerrs = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors");
++
++        if ((rbytes == NULL) || (wbytes == NULL) || (rpkts == NULL) ||
++                (wpkts == NULL) || (ierrs == NULL) || (oerrs == NULL))
++        {
++            PyErr_SetString(PyExc_RuntimeError, "kstat_data_lookup() failed");
++            goto error;
++        }
++
++#if defined(_INT64_TYPE)
++        py_ifc_info = Py_BuildValue("(KKKKkkii)",
++                                    wbytes->value.ui64,
++                                    rbytes->value.ui64,
++                                    wpkts->value.ui64,
++                                    rpkts->value.ui64,
++                                    ierrs->value.ui32,
++                                    oerrs->value.ui32,
++#else
++        py_ifc_info = Py_BuildValue("(kkkkkkii)",
++                                    wbytes->value.ui32,
++                                    rbytes->value.ui32,
++                                    wpkts->value.ui32,
++                                    rpkts->value.ui32,
++                                    ierrs->value.ui32,
++                                    oerrs->value.ui32,
++#endif
++                                    0,  // dropin not supported
++                                    0   // dropout not supported
++                                   );
++        if (!py_ifc_info)
++            goto error;
++        if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info))
++            goto error;
++        Py_DECREF(py_ifc_info);
++        goto next;
++
++next:
++        ksp = ksp->ks_next;
++    }
++
++    kstat_close(kc);
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_ifc_info);
++    Py_DECREF(py_retdict);
++    if (kc != NULL)
++        kstat_close(kc);
++    return NULL;
++}
++
++
++#ifndef EXPER_IP_AND_ALL_IRES
++#define EXPER_IP_AND_ALL_IRES   (1024+4)
++#endif
++
++// a signaler for connections without an actual status
++static int PSUTIL_CONN_NONE = 128;
++
++/*
++ * Return TCP and UDP connections opened by process.
++ * UNIX sockets are excluded.
++ *
++ * Thanks to:
++ * https://github.com/DavidGriffith/finx/blob/master/
++ *     nxsensor-3.5.0-1/src/sysdeps/solaris.c
++ * ...and:
++ * https://hg.java.net/hg/solaris~on-src/file/tip/usr/src/cmd/
++ *     cmd-inet/usr.bin/netstat/netstat.c
++ */
++static PyObject *
++psutil_net_connections(PyObject *self, PyObject *args)
++{
++    long pid;
++    int sd = 0;
++    mib2_tcpConnEntry_t *tp = NULL;
++    mib2_udpEntry_t     *ude;
++#if defined(AF_INET6)
++    mib2_tcp6ConnEntry_t *tp6;
++    mib2_udp6Entry_t     *ude6;
++#endif
++    char buf[512];
++    int i, flags, getcode, num_ent, state;
++    char lip[200], rip[200];
++    int lport, rport;
++    int processed_pid;
++    int databuf_init = 0;
++    struct strbuf ctlbuf, databuf;
++    struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf;
++    struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf;
++    struct T_error_ack   *tea = (struct T_error_ack *)buf;
++    struct opthdr        *mibhdr;
++
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++    PyObject *py_laddr = NULL;
++    PyObject *py_raddr = NULL;
++    PyObject *af_filter = NULL;
++    PyObject *type_filter = NULL;
++
++    if (py_retlist == NULL)
++        return NULL;
++    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
++        goto error;
++    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
++        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
++        goto error;
++    }
++
++    sd = open("/dev/arp", O_RDWR);
++    if (sd == -1) {
++        PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/dev/arp");
++        goto error;
++    }
++
++    /*
++    XXX - These 2 are used in ifconfig.c but they seem unnecessary
++    ret = ioctl(sd, I_PUSH, "tcp");
++    if (ret == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++    ret = ioctl(sd, I_PUSH, "udp");
++    if (ret == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++    */
++
++    // OK, this mess is basically copied and pasted from nxsensor project
++    // which copied and pasted it from netstat source code, mibget()
++    // function.  Also see:
++    // http://stackoverflow.com/questions/8723598/
++    tor->PRIM_type = T_SVR4_OPTMGMT_REQ;
++    tor->OPT_offset = sizeof (struct T_optmgmt_req);
++    tor->OPT_length = sizeof (struct opthdr);
++    tor->MGMT_flags = T_CURRENT;
++    mibhdr = (struct opthdr *)&tor[1];
++    mibhdr->level = EXPER_IP_AND_ALL_IRES;
++    mibhdr->name  = 0;
++    mibhdr->len   = 0;
++
++    ctlbuf.buf = buf;
++    ctlbuf.len = tor->OPT_offset + tor->OPT_length;
++    flags = 0;  // request to be sent in non-priority
++
++    if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) {
++        PyErr_SetFromErrno(PyExc_OSError);
++        goto error;
++    }
++
++    mibhdr = (struct opthdr *)&toa[1];
++    ctlbuf.maxlen = sizeof (buf);
++
++    for (;;) {
++        flags = 0;
++        getcode = getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags);
++
++        if (getcode != MOREDATA ||
++                ctlbuf.len < sizeof (struct T_optmgmt_ack) ||
++                toa->PRIM_type != T_OPTMGMT_ACK ||
++                toa->MGMT_flags != T_SUCCESS)
++        {
++            break;
++        }
++        if (ctlbuf.len >= sizeof (struct T_error_ack) &&
++                tea->PRIM_type == T_ERROR_ACK)
++        {
++            PyErr_SetString(PyExc_RuntimeError, "ERROR_ACK");
++            goto error;
++        }
++        if (getcode == 0 &&
++                ctlbuf.len >= sizeof (struct T_optmgmt_ack) &&
++                toa->PRIM_type == T_OPTMGMT_ACK &&
++                toa->MGMT_flags == T_SUCCESS)
++        {
++            PyErr_SetString(PyExc_RuntimeError, "ERROR_T_OPTMGMT_ACK");
++            goto error;
++        }
++
++        databuf.maxlen = mibhdr->len;
++        databuf.len = 0;
++        databuf.buf = (char *)malloc((int)mibhdr->len);
++        if (!databuf.buf) {
++            PyErr_NoMemory();
++            goto error;
++        }
++        databuf_init = 1;
++
++        flags = 0;
++        getcode = getmsg(sd, (struct strbuf *)0, &databuf, &flags);
++        if (getcode < 0) {
++            PyErr_SetFromErrno(PyExc_OSError);
++            goto error;
++        }
++
++        // TCPv4
++        if (mibhdr->level == MIB2_TCP && mibhdr->name == MIB2_TCP_13) {
++            tp = (mib2_tcpConnEntry_t *)databuf.buf;
++            num_ent = mibhdr->len / sizeof(mib2_tcpConnEntry_t);
++            for (i = 0; i < num_ent; i++, tp++) {
++                processed_pid = tp->tcpConnCreationProcess;
++                if (pid != -1 && processed_pid != pid)
++                    continue;
++                // construct local/remote addresses
++                inet_ntop(AF_INET, &tp->tcpConnLocalAddress, lip, sizeof(lip));
++                inet_ntop(AF_INET, &tp->tcpConnRemAddress, rip, sizeof(rip));
++                lport = tp->tcpConnLocalPort;
++                rport = tp->tcpConnRemPort;
++
++                // contruct python tuple/list
++                py_laddr = Py_BuildValue("(si)", lip, lport);
++                if (!py_laddr)
++                    goto error;
++                if (rport != 0)
++                    py_raddr = Py_BuildValue("(si)", rip, rport);
++                else {
++                    py_raddr = Py_BuildValue("()");
++                }
++                if (!py_raddr)
++                    goto error;
++                state = tp->tcpConnEntryInfo.ce_state;
++
++                // add item
++                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_STREAM,
++                                         py_laddr, py_raddr, state,
++                                         processed_pid);
++                if (!py_tuple)
++                    goto error;
++                if (PyList_Append(py_retlist, py_tuple))
++                    goto error;
++                Py_DECREF(py_tuple);
++            }
++        }
++#if defined(AF_INET6)
++        // TCPv6
++        else if (mibhdr->level == MIB2_TCP6 && mibhdr->name == MIB2_TCP6_CONN)
++        {
++            tp6 = (mib2_tcp6ConnEntry_t *)databuf.buf;
++            num_ent = mibhdr->len / sizeof(mib2_tcp6ConnEntry_t);
++
++            for (i = 0; i < num_ent; i++, tp6++) {
++                processed_pid = tp6->tcp6ConnCreationProcess;
++                if (pid != -1 && processed_pid != pid)
++                    continue;
++                // construct local/remote addresses
++                inet_ntop(AF_INET6, &tp6->tcp6ConnLocalAddress, lip, sizeof(lip));
++                inet_ntop(AF_INET6, &tp6->tcp6ConnRemAddress, rip, sizeof(rip));
++                lport = tp6->tcp6ConnLocalPort;
++                rport = tp6->tcp6ConnRemPort;
++
++                // contruct python tuple/list
++                py_laddr = Py_BuildValue("(si)", lip, lport);
++                if (!py_laddr)
++                    goto error;
++                if (rport != 0)
++                    py_raddr = Py_BuildValue("(si)", rip, rport);
++                else
++                    py_raddr = Py_BuildValue("()");
++                if (!py_raddr)
++                    goto error;
++                state = tp6->tcp6ConnEntryInfo.ce_state;
++
++                // add item
++                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, SOCK_STREAM,
++                                         py_laddr, py_raddr, state, processed_pid);
++                if (!py_tuple)
++                    goto error;
++                if (PyList_Append(py_retlist, py_tuple))
++                    goto error;
++                Py_DECREF(py_tuple);
++            }
++        }
++#endif
++        // UDPv4
++        else if (mibhdr->level == MIB2_UDP || mibhdr->level == MIB2_UDP_ENTRY) {
++            ude = (mib2_udpEntry_t *)databuf.buf;
++            num_ent = mibhdr->len / sizeof(mib2_udpEntry_t);
++            for (i = 0; i < num_ent; i++, ude++) {
++                processed_pid = ude->udpCreationProcess;
++                if (pid != -1 && processed_pid != pid)
++                    continue;
++                // XXX Very ugly hack! It seems we get here only the first
++                // time we bump into a UDPv4 socket.  PID is a very high
++                // number (clearly impossible) and the address does not
++                // belong to any valid interface.  Not sure what else
++                // to do other than skipping.
++                if (processed_pid > 131072)
++                    continue;
++                inet_ntop(AF_INET, &ude->udpLocalAddress, lip, sizeof(lip));
++                lport = ude->udpLocalPort;
++                py_laddr = Py_BuildValue("(si)", lip, lport);
++                if (!py_laddr)
++                    goto error;
++                py_raddr = Py_BuildValue("()");
++                if (!py_raddr)
++                    goto error;
++                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_DGRAM,
++                                         py_laddr, py_raddr, PSUTIL_CONN_NONE,
++                                         processed_pid);
++                if (!py_tuple)
++                    goto error;
++                if (PyList_Append(py_retlist, py_tuple))
++                    goto error;
++                Py_DECREF(py_tuple);
++            }
++        }
++#if defined(AF_INET6)
++        // UDPv6
++        else if (mibhdr->level == MIB2_UDP6 ||
++                    mibhdr->level == MIB2_UDP6_ENTRY)
++            {
++            ude6 = (mib2_udp6Entry_t *)databuf.buf;
++            num_ent = mibhdr->len / sizeof(mib2_udp6Entry_t);
++            for (i = 0; i < num_ent; i++, ude6++) {
++                processed_pid = ude6->udp6CreationProcess;
++                if (pid != -1 && processed_pid != pid)
++                    continue;
++                inet_ntop(AF_INET6, &ude6->udp6LocalAddress, lip, sizeof(lip));
++                lport = ude6->udp6LocalPort;
++                py_laddr = Py_BuildValue("(si)", lip, lport);
++                if (!py_laddr)
++                    goto error;
++                py_raddr = Py_BuildValue("()");
++                if (!py_raddr)
++                    goto error;
++                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, SOCK_DGRAM,
++                                         py_laddr, py_raddr, PSUTIL_CONN_NONE,
++                                         processed_pid);
++                if (!py_tuple)
++                    goto error;
++                if (PyList_Append(py_retlist, py_tuple))
++                    goto error;
++                Py_DECREF(py_tuple);
++            }
++        }
++#endif
++        free(databuf.buf);
++    }
++
++    close(sd);
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_tuple);
++    Py_XDECREF(py_laddr);
++    Py_XDECREF(py_raddr);
++    Py_DECREF(py_retlist);
++    if (databuf_init == 1)
++        free(databuf.buf);
++    if (sd != 0)
++        close(sd);
++    return NULL;
++}
++
++
++static PyObject *
++psutil_boot_time(PyObject *self, PyObject *args)
++{
++    float boot_time = 0.0;
++    struct utmpx *ut;
++
++    while (NULL != (ut = getutxent())) {
++        if (ut->ut_type == BOOT_TIME) {
++            boot_time = (float)ut->ut_tv.tv_sec;
++            break;
++        }
++    }
++    endutent();
++    if (boot_time != 0.0) {
++        return Py_BuildValue("f", boot_time);
++    }
++    else {
++        PyErr_SetString(PyExc_RuntimeError, "can't determine boot time");
++        return NULL;
++    }
++}
++
++
++/*
++ * Return the number of physical CPU cores on the system.
++ */
++static PyObject *
++psutil_cpu_count_phys(PyObject *self, PyObject *args)
++{
++    kstat_ctl_t *kc;
++    kstat_t *ksp;
++    int ncpus = 0;
++
++    kc = kstat_open();
++    if (kc == NULL)
++        goto error;
++    ksp = kstat_lookup(kc, "cpu_info", -1, NULL);
++    if (ksp == NULL)
++        goto error;
++
++    for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
++        if (strcmp(ksp->ks_module, "cpu_info") != 0)
++            continue;
++        if (kstat_read(kc, ksp, NULL) == -1)
++            goto error;
++        ncpus += 1;
++    }
++
++    kstat_close(kc);
++    if (ncpus > 0)
++        return Py_BuildValue("i", ncpus);
++    else
++        goto error;
++
++error:
++    // mimic os.cpu_count()
++    if (kc != NULL)
++        kstat_close(kc);
++    Py_RETURN_NONE;
++}
++
++
++/*
++ * Return stats about a particular network
++ * interface.  References:
++ * https://github.com/dpaleino/wicd/blob/master/wicd/backends/be-ioctl.py
++ * http://www.i-scream.org/libstatgrab/
++ */
++static PyObject*
++psutil_net_if_stats(PyObject* self, PyObject* args)
++{
++    kstat_ctl_t *kc = NULL;
++    kstat_t *ksp;
++    kstat_named_t *knp;
++    int ret;
++    int sock = 0;
++    int duplex;
++    int speed;
++
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_ifc_info = NULL;
++    PyObject *py_is_up = NULL;
++
++    if (py_retdict == NULL)
++        return NULL;
++    kc = kstat_open();
++    if (kc == NULL)
++        goto error;
++    sock = socket(AF_INET, SOCK_DGRAM, 0);
++    if (sock == -1)
++        goto error;
++
++    for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
++        if (strcmp(ksp->ks_class, "net") == 0) {
++            struct ifreq ifr;
++
++            kstat_read(kc, ksp, NULL);
++            if (ksp->ks_type != KSTAT_TYPE_NAMED)
++                continue;
++            if (strcmp(ksp->ks_class, "net") != 0)
++                continue;
++
++            strncpy(ifr.ifr_name, ksp->ks_name, sizeof(ifr.ifr_name));
++            ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
++            if (ret == -1)
++                continue;  // not a network interface
++
++            // is up?
++            if ((ifr.ifr_flags & IFF_UP) != 0) {
++                if ((knp = kstat_data_lookup(ksp, "link_up")) != NULL) {
++                    if (knp->value.ui32 != 0u)
++                        py_is_up = Py_True;
++                    else
++                        py_is_up = Py_False;
++                }
++                else {
++                    py_is_up = Py_True;
++                }
++            }
++            else {
++                py_is_up = Py_False;
++            }
++            Py_INCREF(py_is_up);
++
++            // duplex
++            duplex = 0;  // unknown
++            if ((knp = kstat_data_lookup(ksp, "link_duplex")) != NULL) {
++                if (knp->value.ui32 == 1)
++                    duplex = 1;  // half
++                else if (knp->value.ui32 == 2)
++                    duplex = 2;  // full
++            }
++
++            // speed
++            if ((knp = kstat_data_lookup(ksp, "ifspeed")) != NULL)
++                // expressed in bits per sec, we want mega bits per sec
++                speed = (int)knp->value.ui64 / 1000000;
++            else
++                speed = 0;
++
++            // mtu
++            ret = ioctl(sock, SIOCGIFMTU, &ifr);
++            if (ret == -1)
++                goto error;
++
++            py_ifc_info = Py_BuildValue("(Oiii)", py_is_up, duplex, speed,
++                                        ifr.ifr_mtu);
++            if (!py_ifc_info)
++                goto error;
++            if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info))
++                goto error;
++            Py_DECREF(py_ifc_info);
++        }
++    }
++
++    close(sock);
++    kstat_close(kc);
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_is_up);
++    Py_XDECREF(py_ifc_info);
++    Py_DECREF(py_retdict);
++    if (sock != 0)
++        close(sock);
++    if (kc != NULL)
++        kstat_close(kc);
++    PyErr_SetFromErrno(PyExc_OSError);
++    return NULL;
++}
++
++
++/*
++ * define the psutil C module methods and initialize the module.
++ */
++static PyMethodDef
++PsutilMethods[] =
++{
++    // --- process-related functions
++    {"proc_basic_info", psutil_proc_basic_info, METH_VARARGS,
++     "Return process ppid, rss, vms, ctime, nice, nthreads, status and tty"},
++    {"proc_name_and_args", psutil_proc_name_and_args, METH_VARARGS,
++     "Return process name and args."},
++    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
++     "Return process user and system CPU times."},
++    {"proc_cred", psutil_proc_cred, METH_VARARGS,
++     "Return process uids/gids."},
++    {"query_process_thread", psutil_proc_query_thread, METH_VARARGS,
++     "Return info about a process thread"},
++    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
++     "Return process memory mappings"},
++    {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
++     "Return the number of context switches performed by process"},
++
++    // --- system-related functions
++    {"swap_mem", psutil_swap_mem, METH_VARARGS,
++     "Return information about system swap memory."},
++    {"users", psutil_users, METH_VARARGS,
++     "Return currently connected users."},
++    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
++     "Return disk partitions."},
++    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
++     "Return system per-CPU times."},
++    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
++     "Return a Python dict of tuples for disk I/O statistics."},
++    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
++     "Return a Python dict of tuples for network I/O statistics."},
++    {"boot_time", psutil_boot_time, METH_VARARGS,
++     "Return system boot time in seconds since the EPOCH."},
++    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
++     "Return the number of physical CPUs on the system."},
++    {"net_connections", psutil_net_connections, METH_VARARGS,
++     "Return TCP and UDP syste-wide open connections."},
++    {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
++     "Return NIC stats (isup, duplex, speed, mtu)"},
++
++{NULL, NULL, 0, NULL}
++};
++
++
++struct module_state {
++    PyObject *error;
++};
++
++#if PY_MAJOR_VERSION >= 3
++#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
++#else
++#define GETSTATE(m) (&_state)
++#endif
++
++#if PY_MAJOR_VERSION >= 3
++
++static int
++psutil_sunos_traverse(PyObject *m, visitproc visit, void *arg) {
++    Py_VISIT(GETSTATE(m)->error);
++    return 0;
++}
++
++static int
++psutil_sunos_clear(PyObject *m) {
++    Py_CLEAR(GETSTATE(m)->error);
++    return 0;
++}
++
++static struct PyModuleDef moduledef = {
++    PyModuleDef_HEAD_INIT,
++    "psutil_sunos",
++    NULL,
++    sizeof(struct module_state),
++    PsutilMethods,
++    NULL,
++    psutil_sunos_traverse,
++    psutil_sunos_clear,
++    NULL
++};
++
++#define INITERROR return NULL
++
++PyMODINIT_FUNC PyInit__psutil_sunos(void)
++
++#else
++#define INITERROR return
++
++void init_psutil_sunos(void)
++#endif
++{
++#if PY_MAJOR_VERSION >= 3
++    PyObject *module = PyModule_Create(&moduledef);
++#else
++    PyObject *module = Py_InitModule("_psutil_sunos", PsutilMethods);
++#endif
++    PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
++
++    PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
++    PyModule_AddIntConstant(module, "SRUN", SRUN);
++    PyModule_AddIntConstant(module, "SZOMB", SZOMB);
++    PyModule_AddIntConstant(module, "SSTOP", SSTOP);
++    PyModule_AddIntConstant(module, "SIDL", SIDL);
++    PyModule_AddIntConstant(module, "SONPROC", SONPROC);
++    PyModule_AddIntConstant(module, "SWAIT", SWAIT);
++
++    PyModule_AddIntConstant(module, "PRNODEV", PRNODEV);  // for process tty
++
++    PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
++    PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
++    PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
++    PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
++    PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
++    PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
++    PyModule_AddIntConstant(module, "TCPS_SYN_RCVD", TCPS_SYN_RCVD);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
++    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
++    PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
++    PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
++    // sunos specific
++    PyModule_AddIntConstant(module, "TCPS_IDLE", TCPS_IDLE);
++    // sunos specific
++    PyModule_AddIntConstant(module, "TCPS_BOUND", TCPS_BOUND);
++    PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
++
++    if (module == NULL)
++        INITERROR;
++#if PY_MAJOR_VERSION >= 3
++    return module;
++#endif
++}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_sunos.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_sunos.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,28 @@
++/*
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include <Python.h>
++
++// processes
++static PyObject* psutil_proc_basic_info(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cred(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_name_and_args(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_ctx_switches(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_query_thread(PyObject* self, PyObject* args);
++
++// system
++static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
++static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
++static PyObject* psutil_users(PyObject* self, PyObject* args);
++static PyObject* psutil_net_connections(PyObject* self, PyObject* args);
++static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_windows.c	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_windows.c	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,3411 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ * Windows platform-specific module methods for _psutil_windows
++ */
++
++// Fixes clash between winsock2.h and windows.h
++#define WIN32_LEAN_AND_MEAN
++
++#include <Python.h>
++#include <windows.h>
++#include <Psapi.h>
++#include <time.h>
++#include <lm.h>
++#include <WinIoCtl.h>
++#include <tchar.h>
++#include <tlhelp32.h>
++#include <winsock2.h>
++#include <iphlpapi.h>
++#include <wtsapi32.h>
++#include <ws2tcpip.h>
++
++// Link with Iphlpapi.lib
++#pragma comment(lib, "IPHLPAPI.lib")
++
++#include "_psutil_windows.h"
++#include "_psutil_common.h"
++#include "arch/windows/security.h"
++#include "arch/windows/process_info.h"
++#include "arch/windows/process_handles.h"
++#include "arch/windows/ntextapi.h"
++
++#ifdef __MINGW32__
++#include "arch/windows/glpi.h"
++#endif
++
++
++/*
++ * ============================================================================
++ * Utilities
++ * ============================================================================
++ */
++
++ // a flag for connections without an actual status
++static int PSUTIL_CONN_NONE = 128;
++
++#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
++#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
++#define LO_T ((float)1e-7)
++#define HI_T (LO_T*4294967296.0)
++#define BYTESWAP_USHORT(x) ((((USHORT)(x) << 8) | ((USHORT)(x) >> 8)) & 0xffff)
++#ifndef AF_INET6
++#define AF_INET6 23
++#endif
++#define _psutil_conn_decref_objs() \
++    Py_DECREF(_AF_INET); \
++    Py_DECREF(_AF_INET6);\
++    Py_DECREF(_SOCK_STREAM);\
++    Py_DECREF(_SOCK_DGRAM);
++
++typedef BOOL (WINAPI *LPFN_GLPI)
++    (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,  PDWORD);
++
++// fix for mingw32, see
++// https://github.com/giampaolo/psutil/issues/351#c2
++typedef struct _DISK_PERFORMANCE_WIN_2008 {
++    LARGE_INTEGER BytesRead;
++    LARGE_INTEGER BytesWritten;
++    LARGE_INTEGER ReadTime;
++    LARGE_INTEGER WriteTime;
++    LARGE_INTEGER IdleTime;
++    DWORD         ReadCount;
++    DWORD         WriteCount;
++    DWORD         QueueDepth;
++    DWORD         SplitCount;
++    LARGE_INTEGER QueryTime;
++    DWORD         StorageDeviceNumber;
++    WCHAR         StorageManagerName[8];
++} DISK_PERFORMANCE_WIN_2008;
++
++// --- network connections mingw32 support
++#ifndef _IPRTRMIB_H
++typedef struct _MIB_TCP6ROW_OWNER_PID {
++    UCHAR ucLocalAddr[16];
++    DWORD dwLocalScopeId;
++    DWORD dwLocalPort;
++    UCHAR ucRemoteAddr[16];
++    DWORD dwRemoteScopeId;
++    DWORD dwRemotePort;
++    DWORD dwState;
++    DWORD dwOwningPid;
++} MIB_TCP6ROW_OWNER_PID, *PMIB_TCP6ROW_OWNER_PID;
++
++typedef struct _MIB_TCP6TABLE_OWNER_PID {
++    DWORD dwNumEntries;
++    MIB_TCP6ROW_OWNER_PID table[ANY_SIZE];
++} MIB_TCP6TABLE_OWNER_PID, *PMIB_TCP6TABLE_OWNER_PID;
++#endif
++
++#ifndef __IPHLPAPI_H__
++typedef struct in6_addr {
++    union {
++        UCHAR Byte[16];
++        USHORT Word[8];
++    } u;
++} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
++
++typedef enum _UDP_TABLE_CLASS {
++    UDP_TABLE_BASIC,
++    UDP_TABLE_OWNER_PID,
++    UDP_TABLE_OWNER_MODULE
++} UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;
++
++typedef struct _MIB_UDPROW_OWNER_PID {
++    DWORD dwLocalAddr;
++    DWORD dwLocalPort;
++    DWORD dwOwningPid;
++} MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
++
++typedef struct _MIB_UDPTABLE_OWNER_PID {
++    DWORD dwNumEntries;
++    MIB_UDPROW_OWNER_PID table[ANY_SIZE];
++} MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;
++#endif
++
++typedef struct _MIB_UDP6ROW_OWNER_PID {
++    UCHAR ucLocalAddr[16];
++    DWORD dwLocalScopeId;
++    DWORD dwLocalPort;
++    DWORD dwOwningPid;
++} MIB_UDP6ROW_OWNER_PID, *PMIB_UDP6ROW_OWNER_PID;
++
++typedef struct _MIB_UDP6TABLE_OWNER_PID {
++    DWORD dwNumEntries;
++    MIB_UDP6ROW_OWNER_PID table[ANY_SIZE];
++} MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;
++
++
++PIP_ADAPTER_ADDRESSES
++psutil_get_nic_addresses() {
++    // allocate a 15 KB buffer to start with
++    int outBufLen = 15000;
++    DWORD dwRetVal = 0;
++    ULONG attempts = 0;
++    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
++
++    do {
++        pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
++        if (pAddresses == NULL) {
++            PyErr_NoMemory();
++            return NULL;
++        }
++
++        dwRetVal = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses,
++                                        &outBufLen);
++        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
++            free(pAddresses);
++            pAddresses = NULL;
++        }
++        else {
++            break;
++        }
++
++        attempts++;
++    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (attempts < 3));
++
++    if (dwRetVal != NO_ERROR) {
++        PyErr_SetString(PyExc_RuntimeError, "GetAdaptersAddresses() failed.");
++        return NULL;
++    }
++
++    return pAddresses;
++}
++
++
++/*
++ * ============================================================================
++ * Public Python API
++ * ============================================================================
++ */
++
++
++/*
++ * Return a Python float representing the system uptime expressed in seconds
++ * since the epoch.
++ */
++static PyObject *
++psutil_boot_time(PyObject *self, PyObject *args)
++{
++    double  uptime;
++    time_t pt;
++    FILETIME fileTime;
++    long long ll;
++
++    GetSystemTimeAsFileTime(&fileTime);
++
++    /*
++    HUGE thanks to:
++    http://johnstewien.spaces.live.com/blog/cns!E6885DB5CEBABBC8!831.entry
++
++    This function converts the FILETIME structure to the 32 bit
++    Unix time structure.
++    The time_t is a 32-bit value for the number of seconds since
++    January 1, 1970. A FILETIME is a 64-bit for the number of
++    100-nanosecond periods since January 1, 1601. Convert by
++    subtracting the number of 100-nanosecond period betwee 01-01-1970
++    and 01-01-1601, from time_t the divide by 1e+7 to get to the same
++    base granularity.
++    */
++    ll = (((LONGLONG)(fileTime.dwHighDateTime)) << 32) \
++        + fileTime.dwLowDateTime;
++    pt = (time_t)((ll - 116444736000000000ull) / 10000000ull);
++
++    // XXX - By using GetTickCount() time will wrap around to zero if the
++    // system is run continuously for 49.7 days.
++    uptime = GetTickCount() / 1000.00f;
++    return Py_BuildValue("d", (double)pt - uptime);
++}
++
++
++/*
++ * Return 1 if PID exists in the current process list, else 0.
++ */
++static PyObject *
++psutil_pid_exists(PyObject *self, PyObject *args)
++{
++    long pid;
++    int status;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    status = psutil_pid_is_running(pid);
++    if (-1 == status)
++        return NULL; // exception raised in psutil_pid_is_running()
++    return PyBool_FromLong(status);
++}
++
++
++/*
++ * Return a Python list of all the PIDs running on the system.
++ */
++static PyObject *
++psutil_pids(PyObject *self, PyObject *args)
++{
++    DWORD *proclist = NULL;
++    DWORD numberOfReturnedPIDs;
++    DWORD i;
++    PyObject *pid = NULL;
++    PyObject *retlist = PyList_New(0);
++
++    if (retlist == NULL)
++        return NULL;
++    proclist = psutil_get_pids(&numberOfReturnedPIDs);
++    if (proclist == NULL)
++        goto error;
++
++    for (i = 0; i < numberOfReturnedPIDs; i++) {
++        pid = Py_BuildValue("I", proclist[i]);
++        if (!pid)
++            goto error;
++        if (PyList_Append(retlist, pid))
++            goto error;
++        Py_DECREF(pid);
++    }
++
++    // free C array allocated for PIDs
++    free(proclist);
++    return retlist;
++
++error:
++    Py_XDECREF(pid);
++    Py_DECREF(retlist);
++    if (proclist != NULL)
++        free(proclist);
++    return NULL;
++}
++
++
++/*
++ * Kill a process given its PID.
++ */
++static PyObject *
++psutil_proc_kill(PyObject *self, PyObject *args)
++{
++    HANDLE hProcess;
++    long pid;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (pid == 0)
++        return AccessDenied();
++
++    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
++    if (hProcess == NULL) {
++        if (GetLastError() == ERROR_INVALID_PARAMETER) {
++            // see https://github.com/giampaolo/psutil/issues/24
++            NoSuchProcess();
++        }
++        else {
++            PyErr_SetFromWindowsErr(0);
++        }
++        return NULL;
++    }
++
++    // kill the process
++    if (! TerminateProcess(hProcess, 0)) {
++        PyErr_SetFromWindowsErr(0);
++        CloseHandle(hProcess);
++        return NULL;
++    }
++
++    CloseHandle(hProcess);
++    Py_RETURN_NONE;
++}
++
++
++/*
++ * Wait for process to terminate and return its exit code.
++ */
++static PyObject *
++psutil_proc_wait(PyObject *self, PyObject *args)
++{
++    HANDLE hProcess;
++    DWORD ExitCode;
++    DWORD retVal;
++    long pid;
++    long timeout;
++
++    if (! PyArg_ParseTuple(args, "ll", &pid, &timeout))
++        return NULL;
++    if (pid == 0)
++        return AccessDenied();
++
++    hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
++                           FALSE, pid);
++    if (hProcess == NULL) {
++        if (GetLastError() == ERROR_INVALID_PARAMETER) {
++            // no such process; we do not want to raise NSP but
++            // return None instead.
++            Py_RETURN_NONE;
++        }
++        else {
++            PyErr_SetFromWindowsErr(0);
++            return NULL;
++        }
++    }
++
++    // wait until the process has terminated
++    Py_BEGIN_ALLOW_THREADS
++    retVal = WaitForSingleObject(hProcess, timeout);
++    Py_END_ALLOW_THREADS
++
++    if (retVal == WAIT_FAILED) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(GetLastError());
++    }
++    if (retVal == WAIT_TIMEOUT) {
++        CloseHandle(hProcess);
++        return Py_BuildValue("l", WAIT_TIMEOUT);
++    }
++
++    // get the exit code; note: subprocess module (erroneously?) uses
++    // what returned by WaitForSingleObject
++    if (GetExitCodeProcess(hProcess, &ExitCode) == 0) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(GetLastError());
++    }
++    CloseHandle(hProcess);
++#if PY_MAJOR_VERSION >= 3
++    return PyLong_FromLong((long) ExitCode);
++#else
++    return PyInt_FromLong((long) ExitCode);
++#endif
++}
++
++
++/*
++ * Return a Python tuple (user_time, kernel_time)
++ */
++static PyObject *
++psutil_proc_cpu_times(PyObject *self, PyObject *args)
++{
++    long        pid;
++    HANDLE      hProcess;
++    FILETIME    ftCreate, ftExit, ftKernel, ftUser;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL)
++        return NULL;
++    if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
++        CloseHandle(hProcess);
++        if (GetLastError() == ERROR_ACCESS_DENIED) {
++            // usually means the process has died so we throw a NoSuchProcess
++            // here
++            return NoSuchProcess();
++        }
++        else {
++            PyErr_SetFromWindowsErr(0);
++            return NULL;
++        }
++    }
++
++    CloseHandle(hProcess);
++
++    /*
++     * User and kernel times are represented as a FILETIME structure
++     * wich contains a 64-bit value representing the number of
++     * 100-nanosecond intervals since January 1, 1601 (UTC):
++     * http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
++     * To convert it into a float representing the seconds that the
++     * process has executed in user/kernel mode I borrowed the code
++     * below from Python's Modules/posixmodule.c
++     */
++    return Py_BuildValue(
++       "(dd)",
++       (double)(ftUser.dwHighDateTime * 429.4967296 + \
++                ftUser.dwLowDateTime * 1e-7),
++       (double)(ftKernel.dwHighDateTime * 429.4967296 + \
++                ftKernel.dwLowDateTime * 1e-7)
++   );
++}
++
++
++/*
++ * Return a Python float indicating the process create time expressed in
++ * seconds since the epoch.
++ */
++static PyObject *
++psutil_proc_create_time(PyObject *self, PyObject *args)
++{
++    long        pid;
++    long long   unix_time;
++    DWORD       exitCode;
++    HANDLE      hProcess;
++    BOOL        ret;
++    FILETIME    ftCreate, ftExit, ftKernel, ftUser;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    // special case for PIDs 0 and 4, return system boot time
++    if (0 == pid || 4 == pid)
++        return psutil_boot_time(NULL, NULL);
++
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL)
++        return NULL;
++    if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
++        CloseHandle(hProcess);
++        if (GetLastError() == ERROR_ACCESS_DENIED) {
++            // usually means the process has died so we throw a
++            // NoSuchProcess here
++            return NoSuchProcess();
++        }
++        else {
++            PyErr_SetFromWindowsErr(0);
++            return NULL;
++        }
++    }
++
++    // Make sure the process is not gone as OpenProcess alone seems to be
++    // unreliable in doing so (it seems a previous call to p.wait() makes
++    // it unreliable).
++    // This check is important as creation time is used to make sure the
++    // process is still running.
++    ret = GetExitCodeProcess(hProcess, &exitCode);
++    CloseHandle(hProcess);
++    if (ret != 0) {
++        if (exitCode != STILL_ACTIVE)
++            return NoSuchProcess();
++    }
++    else {
++        // Ignore access denied as it means the process is still alive.
++        // For all other errors, we want an exception.
++        if (GetLastError() != ERROR_ACCESS_DENIED) {
++            PyErr_SetFromWindowsErr(0);
++            return NULL;
++        }
++    }
++
++    /*
++    Convert the FILETIME structure to a Unix time.
++    It's the best I could find by googling and borrowing code here and there.
++    The time returned has a precision of 1 second.
++    */
++    unix_time = ((LONGLONG)ftCreate.dwHighDateTime) << 32;
++    unix_time += ftCreate.dwLowDateTime - 116444736000000000LL;
++    unix_time /= 10000000;
++    return Py_BuildValue("d", (double)unix_time);
++}
++
++
++
++/*
++ * Return the number of logical CPUs.
++ */
++static PyObject *
++psutil_cpu_count_logical(PyObject *self, PyObject *args)
++{
++    SYSTEM_INFO system_info;
++    system_info.dwNumberOfProcessors = 0;
++
++    GetSystemInfo(&system_info);
++    if (system_info.dwNumberOfProcessors == 0)
++        Py_RETURN_NONE;  // mimic os.cpu_count()
++    else
++        return Py_BuildValue("I", system_info.dwNumberOfProcessors);
++}
++
++
++/*
++ * Return the number of physical CPU cores.
++ */
++static PyObject *
++psutil_cpu_count_phys(PyObject *self, PyObject *args)
++{
++    LPFN_GLPI glpi;
++    DWORD rc;
++    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
++    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
++    DWORD length = 0;
++    DWORD offset = 0;
++    int ncpus = 0;
++
++    glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
++                                     "GetLogicalProcessorInformation");
++    if (glpi == NULL)
++        goto return_none;
++
++    while (1) {
++        rc = glpi(buffer, &length);
++        if (rc == FALSE) {
++            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
++                if (buffer)
++                    free(buffer);
++                buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(
++                    length);
++                if (NULL == buffer) {
++                    PyErr_NoMemory();
++                    return NULL;
++                }
++            }
++            else {
++                goto return_none;
++            }
++        }
++        else {
++            break;
++        }
++    }
++
++    ptr = buffer;
++    while (offset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= length) {
++        if (ptr->Relationship == RelationProcessorCore)
++            ncpus += 1;
++        offset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
++        ptr++;
++    }
++
++    free(buffer);
++    if (ncpus == 0)
++        goto return_none;
++    else
++        return Py_BuildValue("i", ncpus);
++
++return_none:
++    // mimic os.cpu_count()
++    if (buffer != NULL)
++        free(buffer);
++    Py_RETURN_NONE;
++}
++
++
++/*
++ * Return process cmdline as a Python list of cmdline arguments.
++ */
++static PyObject *
++psutil_proc_cmdline(PyObject *self, PyObject *args) {
++    long pid;
++    int pid_return;
++    PyObject *arglist;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if ((pid == 0) || (pid == 4))
++        return Py_BuildValue("[]");
++
++    pid_return = psutil_pid_is_running(pid);
++    if (pid_return == 0)
++        return NoSuchProcess();
++    if (pid_return == -1)
++        return NULL;
++
++    // XXX the assumptio below probably needs to go away
++
++    // May fail any of several ReadProcessMemory calls etc. and
++    // not indicate a real problem so we ignore any errors and
++    // just live without commandline.
++    arglist = psutil_get_arg_list(pid);
++    if ( NULL == arglist ) {
++        // carry on anyway, clear any exceptions too
++        PyErr_Clear();
++        return Py_BuildValue("[]");
++    }
++
++    return arglist;
++}
++
++
++/*
++ * Return process executable path.
++ */
++static PyObject *
++psutil_proc_exe(PyObject *self, PyObject *args) {
++    long pid;
++    HANDLE hProcess;
++    wchar_t exe[MAX_PATH];
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
++    if (NULL == hProcess)
++        return NULL;
++    if (GetProcessImageFileNameW(hProcess, exe, MAX_PATH) == 0) {
++        CloseHandle(hProcess);
++        PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++    CloseHandle(hProcess);
++    return Py_BuildValue("u", exe);
++}
++
++
++/*
++ * Return process base name.
++ * Note: psutil_proc_exe() is attempted first because it's faster
++ * but it raise AccessDenied for processes owned by other users
++ * in which case we fall back on using this.
++ */
++static PyObject *
++psutil_proc_name(PyObject *self, PyObject *args) {
++    long pid;
++    int ok;
++    PROCESSENTRY32 pentry;
++    HANDLE hSnapShot;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
++    if (hSnapShot == INVALID_HANDLE_VALUE) {
++        PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++    pentry.dwSize = sizeof(PROCESSENTRY32);
++    ok = Process32First(hSnapShot, &pentry);
++    if (! ok) {
++        CloseHandle(hSnapShot);
++        PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++    while (ok) {
++        if (pentry.th32ProcessID == pid) {
++            CloseHandle(hSnapShot);
++            return Py_BuildValue("s", pentry.szExeFile);
++        }
++        ok = Process32Next(hSnapShot, &pentry);
++    }
++
++    CloseHandle(hSnapShot);
++    NoSuchProcess();
++    return NULL;
++}
++
++
++/*
++ * Return process memory information as a Python tuple.
++ */
++static PyObject *
++psutil_proc_memory_info(PyObject *self, PyObject *args)
++{
++    HANDLE hProcess;
++    DWORD pid;
++#if (_WIN32_WINNT >= 0x0501)  // Windows XP with SP2
++    PROCESS_MEMORY_COUNTERS_EX cnt;
++#else
++    PROCESS_MEMORY_COUNTERS cnt;
++#endif
++    SIZE_T private = 0;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    hProcess = psutil_handle_from_pid(pid);
++    if (NULL == hProcess)
++        return NULL;
++
++    if (! GetProcessMemoryInfo(hProcess, (PPROCESS_MEMORY_COUNTERS)&cnt,
++                               sizeof(cnt))) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(0);
++    }
++
++#if (_WIN32_WINNT >= 0x0501)  // Windows XP with SP2
++    private = cnt.PrivateUsage;
++#endif
++
++    CloseHandle(hProcess);
++
++    // PROCESS_MEMORY_COUNTERS values are defined as SIZE_T which on 64bits
++    // is an (unsigned long long) and on 32bits is an (unsigned int).
++    // "_WIN64" is defined if we're running a 64bit Python interpreter not
++    // exclusively if the *system* is 64bit.
++#if defined(_WIN64)
++    return Py_BuildValue(
++        "(kKKKKKKKKK)",
++        cnt.PageFaultCount,  // unsigned long
++        (unsigned long long)cnt.PeakWorkingSetSize,
++        (unsigned long long)cnt.WorkingSetSize,
++        (unsigned long long)cnt.QuotaPeakPagedPoolUsage,
++        (unsigned long long)cnt.QuotaPagedPoolUsage,
++        (unsigned long long)cnt.QuotaPeakNonPagedPoolUsage,
++        (unsigned long long)cnt.QuotaNonPagedPoolUsage,
++        (unsigned long long)cnt.PagefileUsage,
++        (unsigned long long)cnt.PeakPagefileUsage,
++        (unsigned long long)private);
++#else
++    return Py_BuildValue(
++        "(kIIIIIIIII)",
++        cnt.PageFaultCount,    // unsigned long
++        (unsigned int)cnt.PeakWorkingSetSize,
++        (unsigned int)cnt.WorkingSetSize,
++        (unsigned int)cnt.QuotaPeakPagedPoolUsage,
++        (unsigned int)cnt.QuotaPagedPoolUsage,
++        (unsigned int)cnt.QuotaPeakNonPagedPoolUsage,
++        (unsigned int)cnt.QuotaNonPagedPoolUsage,
++        (unsigned int)cnt.PagefileUsage,
++        (unsigned int)cnt.PeakPagefileUsage,
++        (unsigned int)private);
++#endif
++}
++
++
++/*
++ * Alternative implementation of the one above but bypasses ACCESS DENIED.
++ */
++static PyObject *
++psutil_proc_memory_info_2(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    PSYSTEM_PROCESS_INFORMATION process;
++    PVOID buffer;
++    SIZE_T private;
++    unsigned long pfault_count;
++
++#if defined(_WIN64)
++    unsigned long long m1, m2, m3, m4, m5, m6, m7, m8;
++#else
++    unsigned int m1, m2, m3, m4, m5, m6, m7, m8;
++#endif
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (! psutil_get_proc_info(pid, &process, &buffer))
++        return NULL;
++
++#if (_WIN32_WINNT >= 0x0501)  // Windows XP with SP2
++    private = process->PrivatePageCount;
++#else
++    private = 0;
++#endif
++    pfault_count = process->PageFaultCount;
++
++    m1 = process->PeakWorkingSetSize;
++    m2 = process->WorkingSetSize;
++    m3 = process->QuotaPeakPagedPoolUsage;
++    m4 = process->QuotaPagedPoolUsage;
++    m5 = process->QuotaPeakNonPagedPoolUsage;
++    m6 = process->QuotaNonPagedPoolUsage;
++    m7 = process->PagefileUsage;
++    m8 = process->PeakPagefileUsage;
++
++    free(buffer);
++
++    // SYSTEM_PROCESS_INFORMATION values are defined as SIZE_T which on 64
++    // bits is an (unsigned long long) and on 32bits is an (unsigned int).
++    // "_WIN64" is defined if we're running a 64bit Python interpreter not
++    // exclusively if the *system* is 64bit.
++#if defined(_WIN64)
++    return Py_BuildValue("(kKKKKKKKKK)",
++#else
++    return Py_BuildValue("(kIIIIIIIII)",
++#endif
++        pfault_count, m1, m2, m3, m4, m5, m6, m7, m8, private);
++}
++
++
++/*
++ * Return a Python integer indicating the total amount of physical memory
++ * in bytes.
++ */
++static PyObject *
++psutil_virtual_mem(PyObject *self, PyObject *args)
++{
++    MEMORYSTATUSEX memInfo;
++    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
++
++    if (! GlobalMemoryStatusEx(&memInfo))
++        return PyErr_SetFromWindowsErr(0);
++    return Py_BuildValue("(LLLLLL)",
++                         memInfo.ullTotalPhys,      // total
++                         memInfo.ullAvailPhys,      // avail
++                         memInfo.ullTotalPageFile,  // total page file
++                         memInfo.ullAvailPageFile,  // avail page file
++                         memInfo.ullTotalVirtual,   // total virtual
++                         memInfo.ullAvailVirtual);  // avail virtual
++}
++
++
++/*
++ * Retrieves system CPU timing information as a (user, system, idle)
++ * tuple. On a multiprocessor system, the values returned are the
++ * sum of the designated times across all processors.
++ */
++static PyObject *
++psutil_cpu_times(PyObject *self, PyObject *args)
++{
++    float idle, kernel, user, system;
++    FILETIME idle_time, kernel_time, user_time;
++
++    if (!GetSystemTimes(&idle_time, &kernel_time, &user_time))
++        return PyErr_SetFromWindowsErr(0);
++
++    idle = (float)((HI_T * idle_time.dwHighDateTime) + \
++                   (LO_T * idle_time.dwLowDateTime));
++    user = (float)((HI_T * user_time.dwHighDateTime) + \
++                   (LO_T * user_time.dwLowDateTime));
++    kernel = (float)((HI_T * kernel_time.dwHighDateTime) + \
++                     (LO_T * kernel_time.dwLowDateTime));
++
++    // Kernel time includes idle time.
++    // We return only busy kernel time subtracting idle time from
++    // kernel time.
++    system = (kernel - idle);
++    return Py_BuildValue("(fff)", user, system, idle);
++}
++
++
++/*
++ * Same as above but for all system CPUs.
++ */
++static PyObject *
++psutil_per_cpu_times(PyObject *self, PyObject *args)
++{
++    float idle, kernel, user;
++    typedef DWORD (_stdcall * NTQSI_PROC) (int, PVOID, ULONG, PULONG);
++    NTQSI_PROC NtQuerySystemInformation;
++    HINSTANCE hNtDll;
++    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
++    SYSTEM_INFO si;
++    UINT i;
++    PyObject *arg = NULL;
++    PyObject *retlist = PyList_New(0);
++
++    if (retlist == NULL)
++        return NULL;
++
++    // dynamic linking is mandatory to use NtQuerySystemInformation
++    hNtDll = LoadLibrary(TEXT("ntdll.dll"));
++    if (hNtDll != NULL) {
++        // gets NtQuerySystemInformation address
++        NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
++                                       hNtDll, "NtQuerySystemInformation");
++
++        if (NtQuerySystemInformation != NULL)
++        {
++            // retrives number of processors
++            GetSystemInfo(&si);
++
++            // allocates an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
++            // structures, one per processor
++            sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
++                   malloc(si.dwNumberOfProcessors * \
++                          sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
++            if (sppi != NULL)
++            {
++                // gets cpu time informations
++                if (0 == NtQuerySystemInformation(
++                            SystemProcessorPerformanceInformation,
++                            sppi,
++                            si.dwNumberOfProcessors * sizeof
++                            (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
++                            NULL)
++                   )
++                {
++                    // computes system global times summing each
++                    // processor value
++                    idle = user = kernel = 0;
++                    for (i = 0; i < si.dwNumberOfProcessors; i++) {
++                        arg = NULL;
++                        user = (float)((HI_T * sppi[i].UserTime.HighPart) +
++                                       (LO_T * sppi[i].UserTime.LowPart));
++                        idle = (float)((HI_T * sppi[i].IdleTime.HighPart) +
++                                       (LO_T * sppi[i].IdleTime.LowPart));
++                        kernel = (float)((HI_T * sppi[i].KernelTime.HighPart) +
++                                         (LO_T * sppi[i].KernelTime.LowPart));
++                        // kernel time includes idle time on windows
++                        // we return only busy kernel time subtracting
++                        // idle time from kernel time
++                        arg = Py_BuildValue("(ddd)",
++                                            user,
++                                            kernel - idle,
++                                            idle);
++                        if (!arg)
++                            goto error;
++                        if (PyList_Append(retlist, arg))
++                            goto error;
++                        Py_DECREF(arg);
++                    }
++                    free(sppi);
++                    FreeLibrary(hNtDll);
++                    return retlist;
++
++                }  // END NtQuerySystemInformation
++            }  // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
++        }  // END GetProcAddress
++    }  // END LoadLibrary
++    goto error;
++
++error:
++    Py_XDECREF(arg);
++    Py_DECREF(retlist);
++    if (sppi)
++        free(sppi);
++    if (hNtDll)
++        FreeLibrary(hNtDll);
++    PyErr_SetFromWindowsErr(0);
++    return NULL;
++}
++
++
++/*
++ * Return process current working directory as a Python string.
++ */
++
++static PyObject *
++psutil_proc_cwd(PyObject *self, PyObject *args)
++{
++    long pid;
++    HANDLE processHandle = NULL;
++    PVOID pebAddress;
++    PVOID rtlUserProcParamsAddress;
++    UNICODE_STRING currentDirectory;
++    WCHAR *currentDirectoryContent = NULL;
++    PyObject *returnPyObj = NULL;
++    PyObject *cwd_from_wchar = NULL;
++    PyObject *cwd = NULL;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    processHandle = psutil_handle_from_pid(pid);
++    if (processHandle == NULL)
++        return NULL;
++
++    pebAddress = psutil_get_peb_address(processHandle);
++
++    // get the address of ProcessParameters
++#ifdef _WIN64
++    if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 32,
++                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
++#else
++    if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10,
++                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
++#endif
++    {
++        CloseHandle(processHandle);
++        if (GetLastError() == ERROR_PARTIAL_COPY) {
++            // this occurs quite often with system processes
++            return AccessDenied();
++        }
++        else {
++            return PyErr_SetFromWindowsErr(0);
++        }
++    }
++
++    // Read the currentDirectory UNICODE_STRING structure.
++    // 0x24 refers to "CurrentDirectoryPath" of RTL_USER_PROCESS_PARAMETERS
++    // structure, see:
++    // http://wj32.wordpress.com/2009/01/24/
++    //     howto-get-the-command-line-of-processes/
++#ifdef _WIN64
++    if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 56,
++                           &currentDirectory, sizeof(currentDirectory), NULL))
++#else
++    if (!ReadProcessMemory(processHandle,
++                           (PCHAR)rtlUserProcParamsAddress + 0x24,
++                           &currentDirectory, sizeof(currentDirectory), NULL))
++#endif
++    {
++        CloseHandle(processHandle);
++        if (GetLastError() == ERROR_PARTIAL_COPY) {
++            // this occurs quite often with system processes
++            return AccessDenied();
++        }
++        else {
++            return PyErr_SetFromWindowsErr(0);
++        }
++    }
++
++    // allocate memory to hold cwd
++    currentDirectoryContent = (WCHAR *)malloc(currentDirectory.Length + 1);
++    if (currentDirectoryContent == NULL) {
++        PyErr_NoMemory();
++        goto error;
++    }
++
++    // read cwd
++    if (!ReadProcessMemory(processHandle, currentDirectory.Buffer,
++                           currentDirectoryContent, currentDirectory.Length,
++                           NULL))
++    {
++        if (GetLastError() == ERROR_PARTIAL_COPY) {
++            // this occurs quite often with system processes
++            AccessDenied();
++        }
++        else {
++            PyErr_SetFromWindowsErr(0);
++        }
++        goto error;
++    }
++
++    // null-terminate the string to prevent wcslen from returning
++    // incorrect length the length specifier is in characters, but
++    // currentDirectory.Length is in bytes
++    currentDirectoryContent[(currentDirectory.Length / sizeof(WCHAR))] = '\0';
++
++    // convert wchar array to a Python unicode string, and then to UTF8
++    cwd_from_wchar = PyUnicode_FromWideChar(currentDirectoryContent,
++                                            wcslen(currentDirectoryContent));
++    if (cwd_from_wchar == NULL)
++        goto error;
++
++#if PY_MAJOR_VERSION >= 3
++    cwd = PyUnicode_FromObject(cwd_from_wchar);
++#else
++    cwd = PyUnicode_AsUTF8String(cwd_from_wchar);
++#endif
++    if (cwd == NULL)
++        goto error;
++
++    // decrement the reference count on our temp unicode str to avoid
++    // mem leak
++    returnPyObj = Py_BuildValue("N", cwd);
++    if (!returnPyObj)
++        goto error;
++
++    Py_DECREF(cwd_from_wchar);
++
++    CloseHandle(processHandle);
++    free(currentDirectoryContent);
++    return returnPyObj;
++
++error:
++    Py_XDECREF(cwd_from_wchar);
++    Py_XDECREF(cwd);
++    Py_XDECREF(returnPyObj);
++    if (currentDirectoryContent != NULL)
++        free(currentDirectoryContent);
++    if (processHandle != NULL)
++        CloseHandle(processHandle);
++    return NULL;
++}
++
++
++/*
++ * Resume or suspends a process
++ */
++int
++psutil_proc_suspend_or_resume(DWORD pid, int suspend)
++{
++    // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx
++    HANDLE hThreadSnap = NULL;
++    THREADENTRY32  te32 = {0};
++
++    if (pid == 0) {
++        AccessDenied();
++        return FALSE;
++    }
++
++    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
++    if (hThreadSnap == INVALID_HANDLE_VALUE) {
++        PyErr_SetFromWindowsErr(0);
++        return FALSE;
++    }
++
++    // Fill in the size of the structure before using it
++    te32.dwSize = sizeof(THREADENTRY32);
++
++    if (! Thread32First(hThreadSnap, &te32)) {
++        PyErr_SetFromWindowsErr(0);
++        CloseHandle(hThreadSnap);
++        return FALSE;
++    }
++
++    // Walk the thread snapshot to find all threads of the process.
++    // If the thread belongs to the process, add its information
++    // to the display list.
++    do
++    {
++        if (te32.th32OwnerProcessID == pid)
++        {
++            HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE,
++                                        te32.th32ThreadID);
++            if (hThread == NULL) {
++                PyErr_SetFromWindowsErr(0);
++                CloseHandle(hThread);
++                CloseHandle(hThreadSnap);
++                return FALSE;
++            }
++            if (suspend == 1)
++            {
++                if (SuspendThread(hThread) == (DWORD) - 1) {
++                    PyErr_SetFromWindowsErr(0);
++                    CloseHandle(hThread);
++                    CloseHandle(hThreadSnap);
++                    return FALSE;
++                }
++            }
++            else
++            {
++                if (ResumeThread(hThread) == (DWORD) - 1) {
++                    PyErr_SetFromWindowsErr(0);
++                    CloseHandle(hThread);
++                    CloseHandle(hThreadSnap);
++                    return FALSE;
++                }
++            }
++            CloseHandle(hThread);
++        }
++    } while (Thread32Next(hThreadSnap, &te32));
++
++    CloseHandle(hThreadSnap);
++    return TRUE;
++}
++
++
++static PyObject *
++psutil_proc_suspend(PyObject *self, PyObject *args)
++{
++    long pid;
++    int suspend = 1;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (! psutil_proc_suspend_or_resume(pid, suspend))
++        return NULL;
++    Py_RETURN_NONE;
++}
++
++
++static PyObject *
++psutil_proc_resume(PyObject *self, PyObject *args)
++{
++    long pid;
++    int suspend = 0;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (! psutil_proc_suspend_or_resume(pid, suspend))
++        return NULL;
++    Py_RETURN_NONE;
++}
++
++
++static PyObject *
++psutil_proc_threads(PyObject *self, PyObject *args)
++{
++    HANDLE hThread;
++    THREADENTRY32 te32 = {0};
++    long pid;
++    int pid_return;
++    int rc;
++    FILETIME ftDummy, ftKernel, ftUser;
++    PyObject *retList = PyList_New(0);
++    PyObject *pyTuple = NULL;
++    HANDLE hThreadSnap = NULL;
++
++    if (retList == NULL)
++        return NULL;
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        goto error;
++    if (pid == 0) {
++        // raise AD instead of returning 0 as procexp is able to
++        // retrieve useful information somehow
++        AccessDenied();
++        goto error;
++    }
++
++    pid_return = psutil_pid_is_running(pid);
++    if (pid_return == 0) {
++        NoSuchProcess();
++        goto error;
++    }
++    if (pid_return == -1)
++        goto error;
++
++    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
++    if (hThreadSnap == INVALID_HANDLE_VALUE) {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    // Fill in the size of the structure before using it
++    te32.dwSize = sizeof(THREADENTRY32);
++
++    if (! Thread32First(hThreadSnap, &te32)) {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    // Walk the thread snapshot to find all threads of the process.
++    // If the thread belongs to the process, increase the counter.
++    do {
++        if (te32.th32OwnerProcessID == pid) {
++            pyTuple = NULL;
++            hThread = NULL;
++            hThread = OpenThread(THREAD_QUERY_INFORMATION,
++                                 FALSE, te32.th32ThreadID);
++            if (hThread == NULL) {
++                // thread has disappeared on us
++                continue;
++            }
++
++            rc = GetThreadTimes(hThread, &ftDummy, &ftDummy, &ftKernel,
++                                &ftUser);
++            if (rc == 0) {
++                PyErr_SetFromWindowsErr(0);
++                goto error;
++            }
++
++            /*
++             * User and kernel times are represented as a FILETIME structure
++             * wich contains a 64-bit value representing the number of
++             * 100-nanosecond intervals since January 1, 1601 (UTC):
++             * http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
++             * To convert it into a float representing the seconds that the
++             * process has executed in user/kernel mode I borrowed the code
++             * below from Python's Modules/posixmodule.c
++             */
++            pyTuple = Py_BuildValue(
++                "kdd",
++                te32.th32ThreadID,
++                (double)(ftUser.dwHighDateTime * 429.4967296 + \
++                         ftUser.dwLowDateTime * 1e-7),
++                (double)(ftKernel.dwHighDateTime * 429.4967296 + \
++                         ftKernel.dwLowDateTime * 1e-7));
++            if (!pyTuple)
++                goto error;
++            if (PyList_Append(retList, pyTuple))
++                goto error;
++            Py_DECREF(pyTuple);
++
++            CloseHandle(hThread);
++        }
++    } while (Thread32Next(hThreadSnap, &te32));
++
++    CloseHandle(hThreadSnap);
++    return retList;
++
++error:
++    Py_XDECREF(pyTuple);
++    Py_DECREF(retList);
++    if (hThread != NULL)
++        CloseHandle(hThread);
++    if (hThreadSnap != NULL)
++        CloseHandle(hThreadSnap);
++    return NULL;
++}
++
++
++static PyObject *
++psutil_proc_open_files(PyObject *self, PyObject *args)
++{
++    long       pid;
++    HANDLE     processHandle;
++    DWORD      access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
++    PyObject  *filesList;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    processHandle = psutil_handle_from_pid_waccess(pid, access);
++    if (processHandle == NULL)
++        return NULL;
++    filesList = psutil_get_open_files(pid, processHandle);
++    CloseHandle(processHandle);
++    if (filesList == NULL)
++        return PyErr_SetFromWindowsErr(0);
++    return filesList;
++}
++
++
++/*
++ Accept a filename's drive in native  format like "\Device\HarddiskVolume1\"
++ and return the corresponding drive letter (e.g. "C:\\").
++ If no match is found return an empty string.
++*/
++static PyObject *
++psutil_win32_QueryDosDevice(PyObject *self, PyObject *args)
++{
++    LPCTSTR   lpDevicePath;
++    TCHAR d = TEXT('A');
++    TCHAR     szBuff[5];
++
++    if (!PyArg_ParseTuple(args, "s", &lpDevicePath))
++        return NULL;
++
++    while (d <= TEXT('Z')) {
++        TCHAR szDeviceName[3] = {d, TEXT(':'), TEXT('\0')};
++        TCHAR szTarget[512] = {0};
++        if (QueryDosDevice(szDeviceName, szTarget, 511) != 0) {
++            if (_tcscmp(lpDevicePath, szTarget) == 0) {
++                _stprintf(szBuff, TEXT("%c:"), d);
++                return Py_BuildValue("s", szBuff);
++            }
++        }
++        d++;
++    }
++    return Py_BuildValue("s", "");
++}
++
++
++/*
++ * Return process username as a "DOMAIN//USERNAME" string.
++ */
++static PyObject *
++psutil_proc_username(PyObject *self, PyObject *args)
++{
++    long pid;
++    HANDLE processHandle;
++    HANDLE tokenHandle;
++    PTOKEN_USER user;
++    ULONG bufferSize;
++    PTSTR name;
++    ULONG nameSize;
++    PTSTR domainName;
++    ULONG domainNameSize;
++    SID_NAME_USE nameUse;
++    PTSTR fullName;
++    PyObject *returnObject;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    processHandle = psutil_handle_from_pid_waccess(
++        pid, PROCESS_QUERY_INFORMATION);
++    if (processHandle == NULL)
++        return NULL;
++
++    if (!OpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)) {
++        CloseHandle(processHandle);
++        return PyErr_SetFromWindowsErr(0);
++    }
++
++    CloseHandle(processHandle);
++
++    // Get the user SID.
++
++    bufferSize = 0x100;
++    user = malloc(bufferSize);
++    if (user == NULL)
++        return PyErr_NoMemory();
++
++    if (!GetTokenInformation(tokenHandle, TokenUser, user, bufferSize,
++                             &bufferSize))
++    {
++        free(user);
++        user = malloc(bufferSize);
++        if (user == NULL) {
++            CloseHandle(tokenHandle);
++            return PyErr_NoMemory();
++        }
++        if (!GetTokenInformation(tokenHandle, TokenUser, user, bufferSize,
++                                 &bufferSize))
++        {
++            free(user);
++            CloseHandle(tokenHandle);
++            return PyErr_SetFromWindowsErr(0);
++        }
++    }
++
++    CloseHandle(tokenHandle);
++
++    // resolve the SID to a name
++    nameSize = 0x100;
++    domainNameSize = 0x100;
++
++    name = malloc(nameSize * sizeof(TCHAR));
++    if (name == NULL)
++        return PyErr_NoMemory();
++    domainName = malloc(domainNameSize * sizeof(TCHAR));
++    if (domainName == NULL)
++        return PyErr_NoMemory();
++
++    if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
++                          &domainNameSize, &nameUse))
++    {
++        free(name);
++        free(domainName);
++        name = malloc(nameSize * sizeof(TCHAR));
++        if (name == NULL)
++            return PyErr_NoMemory();
++        domainName = malloc(domainNameSize * sizeof(TCHAR));
++        if (domainName == NULL)
++            return PyErr_NoMemory();
++        if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize,
++                              domainName, &domainNameSize, &nameUse))
++        {
++            free(name);
++            free(domainName);
++            free(user);
++
++            return PyErr_SetFromWindowsErr(0);
++        }
++    }
++
++    nameSize = _tcslen(name);
++    domainNameSize = _tcslen(domainName);
++
++    // build the full username string
++    fullName = malloc((domainNameSize + 1 + nameSize + 1) * sizeof(TCHAR));
++    if (fullName == NULL) {
++        free(name);
++        free(domainName);
++        free(user);
++        return PyErr_NoMemory();
++    }
++    memcpy(fullName, domainName, domainNameSize);
++    fullName[domainNameSize] = '\\';
++    memcpy(&fullName[domainNameSize + 1], name, nameSize);
++    fullName[domainNameSize + 1 + nameSize] = '\0';
++
++    returnObject = PyUnicode_Decode(
++        fullName, _tcslen(fullName), Py_FileSystemDefaultEncoding, "replace");
++
++    free(fullName);
++    free(name);
++    free(domainName);
++    free(user);
++
++    return returnObject;
++}
++
++
++/*
++ * Return a list of network connections opened by a process
++ */
++static PyObject *
++psutil_net_connections(PyObject *self, PyObject *args)
++{
++    static long null_address[4] = { 0, 0, 0, 0 };
++
++    unsigned long pid;
++    PyObject *connectionsList;
++    PyObject *connectionTuple = NULL;
++    PyObject *af_filter = NULL;
++    PyObject *type_filter = NULL;
++
++    PyObject *_AF_INET = PyLong_FromLong((long)AF_INET);
++    PyObject *_AF_INET6 = PyLong_FromLong((long)AF_INET6);
++    PyObject *_SOCK_STREAM = PyLong_FromLong((long)SOCK_STREAM);
++    PyObject *_SOCK_DGRAM = PyLong_FromLong((long)SOCK_DGRAM);
++
++    typedef PSTR (NTAPI * _RtlIpv4AddressToStringA)(struct in_addr *, PSTR);
++    _RtlIpv4AddressToStringA rtlIpv4AddressToStringA;
++    typedef PSTR (NTAPI * _RtlIpv6AddressToStringA)(struct in6_addr *, PSTR);
++    _RtlIpv6AddressToStringA rtlIpv6AddressToStringA;
++    typedef DWORD (WINAPI * _GetExtendedTcpTable)(PVOID, PDWORD, BOOL, ULONG,
++                                                  TCP_TABLE_CLASS, ULONG);
++    _GetExtendedTcpTable getExtendedTcpTable;
++    typedef DWORD (WINAPI * _GetExtendedUdpTable)(PVOID, PDWORD, BOOL, ULONG,
++                                                  UDP_TABLE_CLASS, ULONG);
++    _GetExtendedUdpTable getExtendedUdpTable;
++    PVOID table = NULL;
++    DWORD tableSize;
++    PMIB_TCPTABLE_OWNER_PID tcp4Table;
++    PMIB_UDPTABLE_OWNER_PID udp4Table;
++    PMIB_TCP6TABLE_OWNER_PID tcp6Table;
++    PMIB_UDP6TABLE_OWNER_PID udp6Table;
++    ULONG i;
++    CHAR addressBufferLocal[65];
++    PyObject *addressTupleLocal = NULL;
++    CHAR addressBufferRemote[65];
++    PyObject *addressTupleRemote = NULL;
++
++    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
++        _psutil_conn_decref_objs();
++        return NULL;
++    }
++
++    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
++        _psutil_conn_decref_objs();
++        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
++        return NULL;
++    }
++
++    if (pid != -1) {
++        if (psutil_pid_is_running(pid) == 0) {
++            _psutil_conn_decref_objs();
++            return NoSuchProcess();
++        }
++    }
++
++    // Import some functions.
++    {
++        HMODULE ntdll;
++        HMODULE iphlpapi;
++
++        ntdll = LoadLibrary(TEXT("ntdll.dll"));
++        rtlIpv4AddressToStringA = (_RtlIpv4AddressToStringA)GetProcAddress(
++                                   ntdll, "RtlIpv4AddressToStringA");
++        rtlIpv6AddressToStringA = (_RtlIpv6AddressToStringA)GetProcAddress(
++                                   ntdll, "RtlIpv6AddressToStringA");
++        /* TODO: Check these two function pointers */
++
++        iphlpapi = LoadLibrary(TEXT("iphlpapi.dll"));
++        getExtendedTcpTable = (_GetExtendedTcpTable)GetProcAddress(iphlpapi,
++                              "GetExtendedTcpTable");
++        getExtendedUdpTable = (_GetExtendedUdpTable)GetProcAddress(iphlpapi,
++                              "GetExtendedUdpTable");
++        FreeLibrary(ntdll);
++        FreeLibrary(iphlpapi);
++    }
++
++    if ((getExtendedTcpTable == NULL) || (getExtendedUdpTable == NULL)) {
++        PyErr_SetString(PyExc_NotImplementedError,
++                        "feature not supported on this Windows version");
++        _psutil_conn_decref_objs();
++        return NULL;
++    }
++
++    connectionsList = PyList_New(0);
++    if (connectionsList == NULL) {
++        _psutil_conn_decref_objs();
++        return NULL;
++    }
++
++    // TCP IPv4
++
++    if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
++            (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
++    {
++        table = NULL;
++        connectionTuple = NULL;
++        addressTupleLocal = NULL;
++        addressTupleRemote = NULL;
++        tableSize = 0;
++        getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
++                            TCP_TABLE_OWNER_PID_ALL, 0);
++
++        table = malloc(tableSize);
++        if (table == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++
++        if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
++                                TCP_TABLE_OWNER_PID_ALL, 0) == 0)
++        {
++            tcp4Table = table;
++
++            for (i = 0; i < tcp4Table->dwNumEntries; i++)
++            {
++                if (pid != -1) {
++                    if (tcp4Table->table[i].dwOwningPid != pid) {
++                        continue;
++                    }
++                }
++
++                if (tcp4Table->table[i].dwLocalAddr != 0 ||
++                        tcp4Table->table[i].dwLocalPort != 0)
++                {
++                    struct in_addr addr;
++
++                    addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
++                    rtlIpv4AddressToStringA(&addr, addressBufferLocal);
++                    addressTupleLocal = Py_BuildValue(
++                        "(si)",
++                        addressBufferLocal,
++                        BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
++                }
++                else {
++                    addressTupleLocal = PyTuple_New(0);
++                }
++
++                if (addressTupleLocal == NULL)
++                    goto error;
++
++                // On Windows <= XP, remote addr is filled even if socket
++                // is in LISTEN mode in which case we just ignore it.
++                if ((tcp4Table->table[i].dwRemoteAddr != 0 ||
++                        tcp4Table->table[i].dwRemotePort != 0) &&
++                        (tcp4Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
++                {
++                    struct in_addr addr;
++
++                    addr.S_un.S_addr = tcp4Table->table[i].dwRemoteAddr;
++                    rtlIpv4AddressToStringA(&addr, addressBufferRemote);
++                    addressTupleRemote = Py_BuildValue(
++                        "(si)",
++                        addressBufferRemote,
++                        BYTESWAP_USHORT(tcp4Table->table[i].dwRemotePort));
++                }
++                else
++                {
++                    addressTupleRemote = PyTuple_New(0);
++                }
++
++                if (addressTupleRemote == NULL)
++                    goto error;
++
++                connectionTuple = Py_BuildValue(
++                    "(iiiNNiI)",
++                    -1,
++                    AF_INET,
++                    SOCK_STREAM,
++                    addressTupleLocal,
++                    addressTupleRemote,
++                    tcp4Table->table[i].dwState,
++                    tcp4Table->table[i].dwOwningPid);
++                if (!connectionTuple)
++                    goto error;
++                if (PyList_Append(connectionsList, connectionTuple))
++                    goto error;
++                Py_DECREF(connectionTuple);
++            }
++        }
++
++        free(table);
++    }
++
++    // TCP IPv6
++
++    if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
++            (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
++    {
++        table = NULL;
++        connectionTuple = NULL;
++        addressTupleLocal = NULL;
++        addressTupleRemote = NULL;
++        tableSize = 0;
++        getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
++                            TCP_TABLE_OWNER_PID_ALL, 0);
++
++        table = malloc(tableSize);
++        if (table == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++
++        if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
++                                TCP_TABLE_OWNER_PID_ALL, 0) == 0)
++        {
++            tcp6Table = table;
++
++            for (i = 0; i < tcp6Table->dwNumEntries; i++)
++            {
++                if (pid != -1) {
++                    if (tcp6Table->table[i].dwOwningPid != pid) {
++                        continue;
++                    }
++                }
++
++                if (memcmp(tcp6Table->table[i].ucLocalAddr, null_address, 16)
++                        != 0 || tcp6Table->table[i].dwLocalPort != 0)
++                {
++                    struct in6_addr addr;
++
++                    memcpy(&addr, tcp6Table->table[i].ucLocalAddr, 16);
++                    rtlIpv6AddressToStringA(&addr, addressBufferLocal);
++                    addressTupleLocal = Py_BuildValue(
++                        "(si)",
++                        addressBufferLocal,
++                        BYTESWAP_USHORT(tcp6Table->table[i].dwLocalPort));
++                }
++                else
++                {
++                    addressTupleLocal = PyTuple_New(0);
++                }
++
++                if (addressTupleLocal == NULL)
++                    goto error;
++
++                // On Windows <= XP, remote addr is filled even if socket
++                // is in LISTEN mode in which case we just ignore it.
++                if ((memcmp(tcp6Table->table[i].ucRemoteAddr, null_address, 16)
++                        != 0 ||
++                        tcp6Table->table[i].dwRemotePort != 0) &&
++                        (tcp6Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
++                {
++                    struct in6_addr addr;
++
++                    memcpy(&addr, tcp6Table->table[i].ucRemoteAddr, 16);
++                    rtlIpv6AddressToStringA(&addr, addressBufferRemote);
++                    addressTupleRemote = Py_BuildValue(
++                        "(si)",
++                        addressBufferRemote,
++                        BYTESWAP_USHORT(tcp6Table->table[i].dwRemotePort));
++                }
++                else
++                {
++                    addressTupleRemote = PyTuple_New(0);
++                }
++
++                if (addressTupleRemote == NULL)
++                    goto error;
++
++                connectionTuple = Py_BuildValue(
++                    "(iiiNNiI)",
++                    -1,
++                    AF_INET6,
++                    SOCK_STREAM,
++                    addressTupleLocal,
++                    addressTupleRemote,
++                    tcp6Table->table[i].dwState,
++                    tcp6Table->table[i].dwOwningPid);
++                if (!connectionTuple)
++                    goto error;
++                if (PyList_Append(connectionsList, connectionTuple))
++                    goto error;
++                Py_DECREF(connectionTuple);
++            }
++        }
++
++        free(table);
++    }
++
++    // UDP IPv4
++
++    if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
++            (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
++    {
++        table = NULL;
++        connectionTuple = NULL;
++        addressTupleLocal = NULL;
++        addressTupleRemote = NULL;
++        tableSize = 0;
++        getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
++                            UDP_TABLE_OWNER_PID, 0);
++
++        table = malloc(tableSize);
++        if (table == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++
++        if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
++                                UDP_TABLE_OWNER_PID, 0) == 0)
++        {
++            udp4Table = table;
++
++            for (i = 0; i < udp4Table->dwNumEntries; i++)
++            {
++                if (pid != -1) {
++                    if (udp4Table->table[i].dwOwningPid != pid) {
++                        continue;
++                    }
++                }
++
++                if (udp4Table->table[i].dwLocalAddr != 0 ||
++                    udp4Table->table[i].dwLocalPort != 0)
++                {
++                    struct in_addr addr;
++
++                    addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
++                    rtlIpv4AddressToStringA(&addr, addressBufferLocal);
++                    addressTupleLocal = Py_BuildValue(
++                        "(si)",
++                        addressBufferLocal,
++                        BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
++                }
++                else {
++                    addressTupleLocal = PyTuple_New(0);
++                }
++
++                if (addressTupleLocal == NULL)
++                    goto error;
++
++                connectionTuple = Py_BuildValue(
++                    "(iiiNNiI)",
++                    -1,
++                    AF_INET,
++                    SOCK_DGRAM,
++                    addressTupleLocal,
++                    PyTuple_New(0),
++                    PSUTIL_CONN_NONE,
++                    udp4Table->table[i].dwOwningPid);
++                if (!connectionTuple)
++                    goto error;
++                if (PyList_Append(connectionsList, connectionTuple))
++                    goto error;
++                Py_DECREF(connectionTuple);
++            }
++        }
++
++        free(table);
++    }
++
++    // UDP IPv6
++
++    if ((PySequence_Contains(af_filter, _AF_INET6) == 1) &&
++            (PySequence_Contains(type_filter, _SOCK_DGRAM) == 1))
++    {
++        table = NULL;
++        connectionTuple = NULL;
++        addressTupleLocal = NULL;
++        addressTupleRemote = NULL;
++        tableSize = 0;
++        getExtendedUdpTable(NULL, &tableSize, FALSE,
++                            AF_INET6, UDP_TABLE_OWNER_PID, 0);
++
++        table = malloc(tableSize);
++        if (table == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++
++        if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6,
++                                UDP_TABLE_OWNER_PID, 0) == 0)
++        {
++            udp6Table = table;
++
++            for (i = 0; i < udp6Table->dwNumEntries; i++)
++            {
++                if (pid != -1) {
++                    if (udp6Table->table[i].dwOwningPid != pid) {
++                        continue;
++                    }
++                }
++
++                if (memcmp(udp6Table->table[i].ucLocalAddr, null_address, 16)
++                        != 0 || udp6Table->table[i].dwLocalPort != 0)
++                {
++                    struct in6_addr addr;
++
++                    memcpy(&addr, udp6Table->table[i].ucLocalAddr, 16);
++                    rtlIpv6AddressToStringA(&addr, addressBufferLocal);
++                    addressTupleLocal = Py_BuildValue(
++                        "(si)",
++                        addressBufferLocal,
++                        BYTESWAP_USHORT(udp6Table->table[i].dwLocalPort));
++                }
++                else {
++                    addressTupleLocal = PyTuple_New(0);
++                }
++
++                if (addressTupleLocal == NULL)
++                    goto error;
++
++                connectionTuple = Py_BuildValue(
++                    "(iiiNNiI)",
++                    -1,
++                    AF_INET6,
++                    SOCK_DGRAM,
++                    addressTupleLocal,
++                    PyTuple_New(0),
++                    PSUTIL_CONN_NONE,
++                    udp6Table->table[i].dwOwningPid);
++                if (!connectionTuple)
++                    goto error;
++                if (PyList_Append(connectionsList, connectionTuple))
++                    goto error;
++                Py_DECREF(connectionTuple);
++            }
++        }
++
++        free(table);
++    }
++
++    _psutil_conn_decref_objs();
++    return connectionsList;
++
++error:
++    _psutil_conn_decref_objs();
++    Py_XDECREF(connectionTuple);
++    Py_XDECREF(addressTupleLocal);
++    Py_XDECREF(addressTupleRemote);
++    Py_DECREF(connectionsList);
++    if (table != NULL)
++        free(table);
++    return NULL;
++}
++
++
++/*
++ * Get process priority as a Python integer.
++ */
++static PyObject *
++psutil_proc_priority_get(PyObject *self, PyObject *args)
++{
++    long pid;
++    DWORD priority;
++    HANDLE hProcess;
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++
++    priority = GetPriorityClass(hProcess);
++    CloseHandle(hProcess);
++    if (priority == 0) {
++        PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++    return Py_BuildValue("i", priority);
++}
++
++
++/*
++ * Set process priority.
++ */
++static PyObject *
++psutil_proc_priority_set(PyObject *self, PyObject *args)
++{
++    long pid;
++    int priority;
++    int retval;
++    HANDLE hProcess;
++    DWORD dwDesiredAccess = \
++        PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
++    if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
++        return NULL;
++    }
++
++    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++
++    retval = SetPriorityClass(hProcess, priority);
++    CloseHandle(hProcess);
++    if (retval == 0) {
++        PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++    Py_RETURN_NONE;
++}
++
++
++#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
++/*
++ * Get process IO priority as a Python integer.
++ */
++static PyObject *
++psutil_proc_io_priority_get(PyObject *self, PyObject *args)
++{
++    long pid;
++    HANDLE hProcess;
++    PULONG IoPriority;
++
++    _NtQueryInformationProcess NtQueryInformationProcess =
++        (_NtQueryInformationProcess)GetProcAddress(
++            GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++
++    NtQueryInformationProcess(
++        hProcess,
++        ProcessIoPriority,
++        &IoPriority,
++        sizeof(ULONG),
++        NULL
++    );
++    CloseHandle(hProcess);
++    return Py_BuildValue("i", IoPriority);
++}
++
++
++/*
++ * Set process IO priority.
++ */
++static PyObject *
++psutil_proc_io_priority_set(PyObject *self, PyObject *args)
++{
++    long pid;
++    int prio;
++    HANDLE hProcess;
++
++    _NtSetInformationProcess NtSetInformationProcess =
++        (_NtSetInformationProcess)GetProcAddress(
++            GetModuleHandleA("ntdll.dll"), "NtSetInformationProcess");
++
++    if (NtSetInformationProcess == NULL) {
++        PyErr_SetString(PyExc_RuntimeError,
++                        "couldn't get NtSetInformationProcess");
++        return NULL;
++    }
++
++    if (! PyArg_ParseTuple(args, "li", &pid, &prio)) {
++        return NULL;
++    }
++    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_ALL_ACCESS);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++
++    NtSetInformationProcess(
++        hProcess,
++        ProcessIoPriority,
++        (PVOID)&prio,
++        sizeof((PVOID)prio)
++    );
++
++    CloseHandle(hProcess);
++    Py_RETURN_NONE;
++}
++#endif
++
++
++/*
++ * Return a Python tuple referencing process I/O counters.
++ */
++static PyObject *
++psutil_proc_io_counters(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    HANDLE hProcess;
++    IO_COUNTERS IoCounters;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    hProcess = psutil_handle_from_pid(pid);
++    if (NULL == hProcess) {
++        return NULL;
++    }
++    if (! GetProcessIoCounters(hProcess, &IoCounters)) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(0);
++    }
++    CloseHandle(hProcess);
++    return Py_BuildValue("(KKKK)",
++                         IoCounters.ReadOperationCount,
++                         IoCounters.WriteOperationCount,
++                         IoCounters.ReadTransferCount,
++                         IoCounters.WriteTransferCount);
++}
++
++
++/*
++ * Return process CPU affinity as a bitmask
++ */
++static PyObject *
++psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    HANDLE hProcess;
++    DWORD_PTR proc_mask;
++    DWORD_PTR system_mask;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++    if (GetProcessAffinityMask(hProcess, &proc_mask, &system_mask) == 0) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(0);
++    }
++
++    CloseHandle(hProcess);
++#ifdef _WIN64
++    return Py_BuildValue("K", (unsigned long long)proc_mask);
++#else
++    return Py_BuildValue("k", (unsigned long)proc_mask);
++#endif
++}
++
++
++/*
++ * Set process CPU affinity
++ */
++static PyObject *
++psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    HANDLE hProcess;
++    DWORD dwDesiredAccess = \
++        PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
++    DWORD_PTR mask;
++
++#ifdef _WIN64
++    if (! PyArg_ParseTuple(args, "lK", &pid, &mask))
++#else
++    if (! PyArg_ParseTuple(args, "lk", &pid, &mask))
++#endif
++    {
++        return NULL;
++    }
++    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
++    if (hProcess == NULL) {
++        return NULL;
++    }
++
++    if (SetProcessAffinityMask(hProcess, mask) == 0) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(0);
++    }
++
++    CloseHandle(hProcess);
++    Py_RETURN_NONE;
++}
++
++
++/*
++ * Return True if one of the process threads is in a waiting or
++ * suspended status.
++ */
++static PyObject *
++psutil_proc_is_suspended(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    ULONG i;
++    PSYSTEM_PROCESS_INFORMATION process;
++    PVOID buffer;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (! psutil_get_proc_info(pid, &process, &buffer)) {
++        return NULL;
++    }
++    for (i = 0; i < process->NumberOfThreads; i++) {
++        if (process->Threads[i].ThreadState != Waiting ||
++                process->Threads[i].WaitReason != Suspended)
++        {
++            free(buffer);
++            Py_RETURN_FALSE;
++        }
++    }
++    free(buffer);
++    Py_RETURN_TRUE;
++}
++
++
++/*
++ * Return path's disk total and free as a Python tuple.
++ */
++static PyObject *
++psutil_disk_usage(PyObject *self, PyObject *args)
++{
++    BOOL retval;
++    ULARGE_INTEGER _, total, free;
++    char *path;
++
++    if (PyArg_ParseTuple(args, "u", &path)) {
++        Py_BEGIN_ALLOW_THREADS
++        retval = GetDiskFreeSpaceExW((LPCWSTR)path, &_, &total, &free);
++        Py_END_ALLOW_THREADS
++        goto return_;
++    }
++
++    // on Python 2 we also want to accept plain strings other
++    // than Unicode
++#if PY_MAJOR_VERSION <= 2
++    PyErr_Clear();  // drop the argument parsing error
++    if (PyArg_ParseTuple(args, "s", &path)) {
++        Py_BEGIN_ALLOW_THREADS
++        retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
++        Py_END_ALLOW_THREADS
++        goto return_;
++    }
++#endif
++
++    return NULL;
++
++return_:
++    if (retval == 0)
++        return PyErr_SetFromWindowsErr(0);
++    else
++        return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
++}
++
++
++/*
++ * Return a Python list of named tuples with overall network I/O information
++ */
++static PyObject *
++psutil_net_io_counters(PyObject *self, PyObject *args)
++{
++    char ifname[MAX_PATH];
++    DWORD dwRetVal = 0;
++    MIB_IFROW *pIfRow = NULL;
++    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
++    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
++
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_nic_info = NULL;
++    PyObject *py_nic_name = NULL;
++
++    if (py_retdict == NULL)
++        return NULL;
++    pAddresses = psutil_get_nic_addresses();
++    if (pAddresses == NULL)
++        goto error;
++    pCurrAddresses = pAddresses;
++
++    while (pCurrAddresses) {
++        py_nic_name = NULL;
++        py_nic_info = NULL;
++        pIfRow = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
++
++        if (pIfRow == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++
++        pIfRow->dwIndex = pCurrAddresses->IfIndex;
++        dwRetVal = GetIfEntry(pIfRow);
++        if (dwRetVal != NO_ERROR) {
++            PyErr_SetString(PyExc_RuntimeError, "GetIfEntry() failed.");
++            goto error;
++        }
++
++        py_nic_info = Py_BuildValue("(kkkkkkkk)",
++                                    pIfRow->dwOutOctets,
++                                    pIfRow->dwInOctets,
++                                    pIfRow->dwOutUcastPkts,
++                                    pIfRow->dwInUcastPkts,
++                                    pIfRow->dwInErrors,
++                                    pIfRow->dwOutErrors,
++                                    pIfRow->dwInDiscards,
++                                    pIfRow->dwOutDiscards);
++        if (!py_nic_info)
++            goto error;
++
++        sprintf(ifname, "%wS", pCurrAddresses->FriendlyName);
++        py_nic_name = PyUnicode_Decode(
++            ifname, _tcslen(ifname), Py_FileSystemDefaultEncoding, "replace");
++
++        if (py_nic_name == NULL)
++            goto error;
++        if (PyDict_SetItem(py_retdict, py_nic_name, py_nic_info))
++            goto error;
++        Py_XDECREF(py_nic_name);
++        Py_XDECREF(py_nic_info);
++
++        free(pIfRow);
++        pCurrAddresses = pCurrAddresses->Next;
++    }
++
++    free(pAddresses);
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_nic_name);
++    Py_XDECREF(py_nic_info);
++    Py_DECREF(py_retdict);
++    if (pAddresses != NULL)
++        free(pAddresses);
++    if (pIfRow != NULL)
++        free(pIfRow);
++    return NULL;
++}
++
++
++/*
++ * Return a Python dict of tuples for disk I/O information
++ */
++static PyObject *
++psutil_disk_io_counters(PyObject *self, PyObject *args)
++{
++    DISK_PERFORMANCE_WIN_2008 diskPerformance;
++    DWORD dwSize;
++    HANDLE hDevice = NULL;
++    char szDevice[MAX_PATH];
++    char szDeviceDisplay[MAX_PATH];
++    int devNum;
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_disk_info = NULL;
++    if (py_retdict == NULL) {
++        return NULL;
++    }
++
++    // Apparently there's no way to figure out how many times we have
++    // to iterate in order to find valid drives.
++    // Let's assume 32, which is higher than 26, the number of letters
++    // in the alphabet (from A:\ to Z:\).
++    for (devNum = 0; devNum <= 32; ++devNum) {
++        py_disk_info = NULL;
++        sprintf(szDevice, "\\\\.\\PhysicalDrive%d", devNum);
++        hDevice = CreateFile(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
++                             NULL, OPEN_EXISTING, 0, NULL);
++
++        if (hDevice == INVALID_HANDLE_VALUE) {
++            continue;
++        }
++        if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
++                            &diskPerformance, sizeof(diskPerformance),
++                            &dwSize, NULL))
++        {
++            sprintf(szDeviceDisplay, "PhysicalDrive%d", devNum);
++            py_disk_info = Py_BuildValue(
++                "(IILLKK)",
++                diskPerformance.ReadCount,
++                diskPerformance.WriteCount,
++                diskPerformance.BytesRead,
++                diskPerformance.BytesWritten,
++                (unsigned long long)(diskPerformance.ReadTime.QuadPart * 10) / 1000,
++                (unsigned long long)(diskPerformance.WriteTime.QuadPart * 10) / 1000);
++            if (!py_disk_info)
++                goto error;
++            if (PyDict_SetItemString(py_retdict, szDeviceDisplay,
++                                     py_disk_info))
++            {
++                goto error;
++            }
++            Py_XDECREF(py_disk_info);
++        }
++        else {
++            // XXX we might get here with ERROR_INSUFFICIENT_BUFFER when
++            // compiling with mingw32; not sure what to do.
++            // return PyErr_SetFromWindowsErr(0);
++            ;;
++        }
++
++        CloseHandle(hDevice);
++    }
++
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_disk_info);
++    Py_DECREF(py_retdict);
++    if (hDevice != NULL)
++        CloseHandle(hDevice);
++    return NULL;
++}
++
++
++static char *psutil_get_drive_type(int type)
++{
++    switch (type) {
++        case DRIVE_FIXED:
++            return "fixed";
++        case DRIVE_CDROM:
++            return "cdrom";
++        case DRIVE_REMOVABLE:
++            return "removable";
++        case DRIVE_UNKNOWN:
++            return "unknown";
++        case DRIVE_NO_ROOT_DIR:
++            return "unmounted";
++        case DRIVE_REMOTE:
++            return "remote";
++        case DRIVE_RAMDISK:
++            return "ramdisk";
++        default:
++            return "?";
++    }
++}
++
++
++#ifndef _ARRAYSIZE
++#define _ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
++#endif
++
++/*
++ * Return disk partitions as a list of tuples such as
++ * (drive_letter, drive_letter, type, "")
++ */
++static PyObject *
++psutil_disk_partitions(PyObject *self, PyObject *args)
++{
++    DWORD num_bytes;
++    char drive_strings[255];
++    char *drive_letter = drive_strings;
++    int all;
++    int type;
++    int ret;
++    char opts[20];
++    LPTSTR fs_type[MAX_PATH + 1] = { 0 };
++    DWORD pflags = 0;
++    PyObject *py_all;
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++
++    if (py_retlist == NULL) {
++        return NULL;
++    }
++
++    // avoid to visualize a message box in case something goes wrong
++    // see https://github.com/giampaolo/psutil/issues/264
++    SetErrorMode(SEM_FAILCRITICALERRORS);
++
++    if (! PyArg_ParseTuple(args, "O", &py_all)) {
++        goto error;
++    }
++    all = PyObject_IsTrue(py_all);
++
++    Py_BEGIN_ALLOW_THREADS
++    num_bytes = GetLogicalDriveStrings(254, drive_letter);
++    Py_END_ALLOW_THREADS
++
++    if (num_bytes == 0) {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    while (*drive_letter != 0) {
++        py_tuple = NULL;
++        opts[0] = 0;
++        fs_type[0] = 0;
++
++        Py_BEGIN_ALLOW_THREADS
++        type = GetDriveType(drive_letter);
++        Py_END_ALLOW_THREADS
++
++        // by default we only show hard drives and cd-roms
++        if (all == 0) {
++            if ((type == DRIVE_UNKNOWN) ||
++                    (type == DRIVE_NO_ROOT_DIR) ||
++                    (type == DRIVE_REMOTE) ||
++                    (type == DRIVE_RAMDISK)) {
++                goto next;
++            }
++            // floppy disk: skip it by default as it introduces a
++            // considerable slowdown.
++            if ((type == DRIVE_REMOVABLE) &&
++                    (strcmp(drive_letter, "A:\\")  == 0)) {
++                goto next;
++            }
++        }
++
++        ret = GetVolumeInformation(
++            (LPCTSTR)drive_letter, NULL, _ARRAYSIZE(drive_letter),
++            NULL, NULL, &pflags, (LPTSTR)fs_type, _ARRAYSIZE(fs_type));
++        if (ret == 0) {
++            // We might get here in case of a floppy hard drive, in
++            // which case the error is (21, "device not ready").
++            // Let's pretend it didn't happen as we already have
++            // the drive name and type ('removable').
++            strcat(opts, "");
++            SetLastError(0);
++        }
++        else {
++            if (pflags & FILE_READ_ONLY_VOLUME) {
++                strcat(opts, "ro");
++            }
++            else {
++                strcat(opts, "rw");
++            }
++            if (pflags & FILE_VOLUME_IS_COMPRESSED) {
++                strcat(opts, ",compressed");
++            }
++        }
++
++        if (strlen(opts) > 0) {
++            strcat(opts, ",");
++        }
++        strcat(opts, psutil_get_drive_type(type));
++
++        py_tuple = Py_BuildValue(
++            "(ssss)",
++            drive_letter,
++            drive_letter,
++            fs_type,  // either FAT, FAT32, NTFS, HPFS, CDFS, UDF or NWFS
++            opts);
++        if (!py_tuple)
++            goto error;
++        if (PyList_Append(py_retlist, py_tuple))
++            goto error;
++        Py_DECREF(py_tuple);
++        goto next;
++
++next:
++        drive_letter = strchr(drive_letter, 0) + 1;
++    }
++
++    SetErrorMode(0);
++    return py_retlist;
++
++error:
++    SetErrorMode(0);
++    Py_XDECREF(py_tuple);
++    Py_DECREF(py_retlist);
++    return NULL;
++}
++
++
++#ifdef UNICODE
++#define WTSOpenServer WTSOpenServerW
++#else
++#define WTSOpenServer WTSOpenServerA
++#endif
++
++
++/*
++ * Return a Python dict of tuples for disk I/O information
++ */
++static PyObject *
++psutil_users(PyObject *self, PyObject *args)
++{
++    HANDLE hServer = NULL;
++    LPTSTR buffer_user = NULL;
++    LPTSTR buffer_addr = NULL;
++    PWTS_SESSION_INFO sessions = NULL;
++    DWORD count;
++    DWORD i;
++    DWORD sessionId;
++    DWORD bytes;
++    PWTS_CLIENT_ADDRESS address;
++    char address_str[50];
++    long long unix_time;
++
++    PWINSTATIONQUERYINFORMATIONW WinStationQueryInformationW;
++    WINSTATION_INFO station_info;
++    HINSTANCE hInstWinSta = NULL;
++    ULONG returnLen;
++
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++    PyObject *py_address = NULL;
++    PyObject *py_buffer_user_encoded = NULL;
++
++    if (py_retlist == NULL) {
++        return NULL;
++    }
++
++    hInstWinSta = LoadLibraryA("winsta.dll");
++    WinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW) \
++        GetProcAddress(hInstWinSta, "WinStationQueryInformationW");
++
++    hServer = WTSOpenServer('\0');
++    if (hServer == NULL) {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    if (WTSEnumerateSessions(hServer, 0, 1, &sessions, &count) == 0) {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    for (i = 0; i < count; i++) {
++        py_address = NULL;
++        py_tuple = NULL;
++        sessionId = sessions[i].SessionId;
++        if (buffer_user != NULL) {
++            WTSFreeMemory(buffer_user);
++        }
++        if (buffer_addr != NULL) {
++            WTSFreeMemory(buffer_addr);
++        }
++
++        buffer_user = NULL;
++        buffer_addr = NULL;
++
++        // username
++        bytes = 0;
++        if (WTSQuerySessionInformation(hServer, sessionId, WTSUserName,
++                                       &buffer_user, &bytes) == 0) {
++            PyErr_SetFromWindowsErr(0);
++            goto error;
++        }
++        if (bytes == 1) {
++            continue;
++        }
++
++        // address
++        bytes = 0;
++        if (WTSQuerySessionInformation(hServer, sessionId, WTSClientAddress,
++                                       &buffer_addr, &bytes) == 0) {
++            PyErr_SetFromWindowsErr(0);
++            goto error;
++        }
++
++        address = (PWTS_CLIENT_ADDRESS)buffer_addr;
++        if (address->AddressFamily == 0) {  // AF_INET
++            sprintf(address_str,
++                    "%u.%u.%u.%u",
++                    address->Address[0],
++                    address->Address[1],
++                    address->Address[2],
++                    address->Address[3]);
++            py_address = Py_BuildValue("s", address_str);
++            if (!py_address)
++                goto error;
++        }
++        else {
++            py_address = Py_None;
++        }
++
++        // login time
++        if (!WinStationQueryInformationW(hServer,
++                                         sessionId,
++                                         WinStationInformation,
++                                         &station_info,
++                                         sizeof(station_info),
++                                         &returnLen))
++        {
++            goto error;
++        }
++
++        unix_time = ((LONGLONG)station_info.ConnectTime.dwHighDateTime) << 32;
++        unix_time += \
++            station_info.ConnectTime.dwLowDateTime - 116444736000000000LL;
++        unix_time /= 10000000;
++
++        py_buffer_user_encoded = PyUnicode_Decode(
++            buffer_user, _tcslen(buffer_user), Py_FileSystemDefaultEncoding,
++            "replace");
++        py_tuple = Py_BuildValue("OOd", py_buffer_user_encoded, py_address,
++                                 (double)unix_time);
++        if (!py_tuple)
++            goto error;
++        if (PyList_Append(py_retlist, py_tuple))
++            goto error;
++        Py_XDECREF(py_buffer_user_encoded);
++        Py_XDECREF(py_address);
++        Py_XDECREF(py_tuple);
++    }
++
++    WTSCloseServer(hServer);
++    WTSFreeMemory(sessions);
++    WTSFreeMemory(buffer_user);
++    WTSFreeMemory(buffer_addr);
++    FreeLibrary(hInstWinSta);
++    return py_retlist;
++
++error:
++    Py_XDECREF(py_buffer_user_encoded);
++    Py_XDECREF(py_tuple);
++    Py_XDECREF(py_address);
++    Py_DECREF(py_retlist);
++
++    if (hInstWinSta != NULL) {
++        FreeLibrary(hInstWinSta);
++    }
++    if (hServer != NULL) {
++        WTSCloseServer(hServer);
++    }
++    if (sessions != NULL) {
++        WTSFreeMemory(sessions);
++    }
++    if (buffer_user != NULL) {
++        WTSFreeMemory(buffer_user);
++    }
++    if (buffer_addr != NULL) {
++        WTSFreeMemory(buffer_addr);
++    }
++    return NULL;
++}
++
++
++/*
++ * Return the number of handles opened by process.
++ */
++static PyObject *
++psutil_proc_num_handles(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    HANDLE hProcess;
++    DWORD handleCount;
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    hProcess = psutil_handle_from_pid(pid);
++    if (NULL == hProcess) {
++        return NULL;
++    }
++    if (! GetProcessHandleCount(hProcess, &handleCount)) {
++        CloseHandle(hProcess);
++        return PyErr_SetFromWindowsErr(0);
++    }
++    CloseHandle(hProcess);
++    return Py_BuildValue("k", handleCount);
++}
++
++
++/*
++ * Get various process information by using NtQuerySystemInformation.
++ * We use this as a fallback when faster functions fail with access
++ * denied. This is slower because it iterates over all processes.
++ * Returned tuple includes the following process info:
++ *
++ * - num_threads
++ * - ctx_switches
++ * - num_handles (fallback)
++ * - user/kernel times (fallback)
++ * - create time (fallback)
++ * - io counters (fallback)
++ */
++static PyObject *
++psutil_proc_info(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    PSYSTEM_PROCESS_INFORMATION process;
++    PVOID buffer;
++    ULONG num_handles;
++    ULONG i;
++    ULONG ctx_switches = 0;
++    double user_time;
++    double kernel_time;
++    long long create_time;
++    int num_threads;
++    LONGLONG io_rcount, io_wcount, io_rbytes, io_wbytes;
++
++
++    if (! PyArg_ParseTuple(args, "l", &pid))
++        return NULL;
++    if (! psutil_get_proc_info(pid, &process, &buffer))
++        return NULL;
++
++    num_handles = process->HandleCount;
++    for (i = 0; i < process->NumberOfThreads; i++)
++        ctx_switches += process->Threads[i].ContextSwitches;
++    user_time = (double)process->UserTime.HighPart * 429.4967296 + \
++                (double)process->UserTime.LowPart * 1e-7;
++    kernel_time = (double)process->KernelTime.HighPart * 429.4967296 + \
++                  (double)process->KernelTime.LowPart * 1e-7;
++    // Convert the LARGE_INTEGER union to a Unix time.
++    // It's the best I could find by googling and borrowing code here
++    // and there. The time returned has a precision of 1 second.
++    if (0 == pid || 4 == pid) {
++        // the python module will translate this into BOOT_TIME later
++        create_time = 0;
++    }
++    else {
++        create_time = ((LONGLONG)process->CreateTime.HighPart) << 32;
++        create_time += process->CreateTime.LowPart - 116444736000000000LL;
++        create_time /= 10000000;
++    }
++    num_threads = (int)process->NumberOfThreads;
++    io_rcount = process->ReadOperationCount.QuadPart;
++    io_wcount = process->WriteOperationCount.QuadPart;
++    io_rbytes = process->ReadTransferCount.QuadPart;
++    io_wbytes = process->WriteTransferCount.QuadPart;
++    free(buffer);
++
++    return Py_BuildValue(
++        "kkdddiKKKK",
++        num_handles,
++        ctx_switches,
++        user_time,
++        kernel_time,
++        (double)create_time,
++        num_threads,
++        io_rcount,
++        io_wcount,
++        io_rbytes,
++        io_wbytes
++    );
++}
++
++
++static char *get_region_protection_string(ULONG protection)
++{
++    switch (protection & 0xff) {
++        case PAGE_NOACCESS:
++            return "";
++        case PAGE_READONLY:
++            return "r";
++        case PAGE_READWRITE:
++            return "rw";
++        case PAGE_WRITECOPY:
++            return "wc";
++        case PAGE_EXECUTE:
++            return "x";
++        case PAGE_EXECUTE_READ:
++            return "xr";
++        case PAGE_EXECUTE_READWRITE:
++            return "xrw";
++        case PAGE_EXECUTE_WRITECOPY:
++            return "xwc";
++        default:
++            return "?";
++    }
++}
++
++
++/*
++ * Return a list of process's memory mappings.
++ */
++static PyObject *
++psutil_proc_memory_maps(PyObject *self, PyObject *args)
++{
++    DWORD pid;
++    HANDLE hProcess = NULL;
++    MEMORY_BASIC_INFORMATION basicInfo;
++    PVOID baseAddress;
++    PVOID previousAllocationBase;
++    CHAR mappedFileName[MAX_PATH];
++    SYSTEM_INFO system_info;
++    LPVOID maxAddr;
++    PyObject *py_list = PyList_New(0);
++    PyObject *py_tuple = NULL;
++
++    if (py_list == NULL) {
++        return NULL;
++    }
++    if (! PyArg_ParseTuple(args, "l", &pid)) {
++        goto error;
++    }
++    hProcess = psutil_handle_from_pid(pid);
++    if (NULL == hProcess) {
++        goto error;
++    }
++
++    GetSystemInfo(&system_info);
++    maxAddr = system_info.lpMaximumApplicationAddress;
++    baseAddress = NULL;
++    previousAllocationBase = NULL;
++
++    while (VirtualQueryEx(hProcess, baseAddress, &basicInfo,
++                          sizeof(MEMORY_BASIC_INFORMATION)))
++    {
++        py_tuple = NULL;
++        if (baseAddress > maxAddr) {
++            break;
++        }
++        if (GetMappedFileNameA(hProcess, baseAddress, mappedFileName,
++                               sizeof(mappedFileName)))
++        {
++            py_tuple = Py_BuildValue(
++                "(kssI)",
++                (unsigned long)baseAddress,
++                get_region_protection_string(basicInfo.Protect),
++                mappedFileName,
++                basicInfo.RegionSize);
++            if (!py_tuple)
++                goto error;
++            if (PyList_Append(py_list, py_tuple))
++                goto error;
++            Py_DECREF(py_tuple);
++        }
++        previousAllocationBase = basicInfo.AllocationBase;
++        baseAddress = (PCHAR)baseAddress + basicInfo.RegionSize;
++    }
++
++    CloseHandle(hProcess);
++    return py_list;
++
++error:
++    Py_XDECREF(py_tuple);
++    Py_DECREF(py_list);
++    if (hProcess != NULL)
++        CloseHandle(hProcess);
++    return NULL;
++}
++
++
++/*
++ * Return a {pid:ppid, ...} dict for all running processes.
++ */
++static PyObject *
++psutil_ppid_map(PyObject *self, PyObject *args)
++{
++    PyObject *pid = NULL;
++    PyObject *ppid = NULL;
++    PyObject *py_retdict = PyDict_New();
++    HANDLE handle = NULL;
++    PROCESSENTRY32 pe = {0};
++    pe.dwSize = sizeof(PROCESSENTRY32);
++
++    if (py_retdict == NULL)
++        return NULL;
++    handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
++    if (handle == INVALID_HANDLE_VALUE) {
++        PyErr_SetFromWindowsErr(0);
++        Py_DECREF(py_retdict);
++        return NULL;
++    }
++
++    if (Process32First(handle, &pe)) {
++        do {
++            pid = Py_BuildValue("I", pe.th32ProcessID);
++            if (pid == NULL)
++                goto error;
++            ppid = Py_BuildValue("I", pe.th32ParentProcessID);
++            if (ppid == NULL)
++                goto error;
++            if (PyDict_SetItem(py_retdict, pid, ppid))
++                goto error;
++            Py_DECREF(pid);
++            Py_DECREF(ppid);
++        } while (Process32Next(handle, &pe));
++    }
++
++    CloseHandle(handle);
++    return py_retdict;
++
++error:
++    Py_XDECREF(pid);
++    Py_XDECREF(ppid);
++    Py_DECREF(py_retdict);
++    CloseHandle(handle);
++    return NULL;
++}
++
++
++/*
++ * Return NICs addresses.
++ */
++
++static PyObject *
++psutil_net_if_addrs(PyObject *self, PyObject *args)
++{
++    unsigned int i = 0;
++    ULONG family;
++    PCTSTR intRet;
++    char *ptr;
++    char buff[100];
++    char ifname[MAX_PATH];
++    DWORD bufflen = 100;
++    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
++    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
++    PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
++
++    PyObject *py_retlist = PyList_New(0);
++    PyObject *py_tuple = NULL;
++    PyObject *py_address = NULL;
++    PyObject *py_mac_address = NULL;
++
++    if (py_retlist == NULL)
++        return NULL;
++
++    pAddresses = psutil_get_nic_addresses();
++    if (pAddresses == NULL)
++        goto error;
++    pCurrAddresses = pAddresses;
++
++    while (pCurrAddresses) {
++        pUnicast = pCurrAddresses->FirstUnicastAddress;
++        sprintf(ifname, "%wS", pCurrAddresses->FriendlyName);
++
++        // MAC address
++        if (pCurrAddresses->PhysicalAddressLength != 0) {
++            ptr = buff;
++            *ptr = '\0';
++            for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength; i++) {
++                if (i == (pCurrAddresses->PhysicalAddressLength - 1)) {
++                    sprintf(ptr, "%.2X\n",
++                            (int)pCurrAddresses->PhysicalAddress[i]);
++                }
++                else {
++                    sprintf(ptr, "%.2X-",
++                            (int)pCurrAddresses->PhysicalAddress[i]);
++                }
++                ptr += 3;
++            }
++            *--ptr = '\0';
++
++#if PY_MAJOR_VERSION >= 3
++            py_mac_address = PyUnicode_FromString(buff);
++#else
++            py_mac_address = PyString_FromString(buff);
++#endif
++            if (py_mac_address == NULL)
++                goto error;
++
++            Py_INCREF(Py_None);
++            Py_INCREF(Py_None);
++            py_tuple = Py_BuildValue(
++                "(siOOO)",
++                ifname,
++                -1,  // this will be converted later to AF_LINK
++                py_mac_address,
++                Py_None,
++                Py_None
++            );
++            if (! py_tuple)
++                goto error;
++            if (PyList_Append(py_retlist, py_tuple))
++                goto error;
++            Py_DECREF(py_tuple);
++            Py_DECREF(py_mac_address);
++        }
++
++        // find out the IP address associated with the NIC
++        if (pUnicast != NULL) {
++            for (i = 0; pUnicast != NULL; i++) {
++                family = pUnicast->Address.lpSockaddr->sa_family;
++                if (family == AF_INET) {
++                    struct sockaddr_in *sa_in = (struct sockaddr_in *)
++                        pUnicast->Address.lpSockaddr;
++                    intRet = inet_ntop(AF_INET, &(sa_in->sin_addr), buff,
++                                       bufflen);
++                }
++                else if (family == AF_INET6) {
++                    struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)
++                        pUnicast->Address.lpSockaddr;
++                    intRet = inet_ntop(AF_INET6, &(sa_in6->sin6_addr),
++                                       buff, bufflen);
++                }
++                else {
++                    // we should never get here
++                    pUnicast = pUnicast->Next;
++                    continue;
++                }
++
++                if (intRet == NULL) {
++                    PyErr_SetFromWindowsErr(GetLastError());
++                    goto error;
++                }
++#if PY_MAJOR_VERSION >= 3
++                py_address = PyUnicode_FromString(buff);
++#else
++                py_address = PyString_FromString(buff);
++#endif
++                if (py_address == NULL)
++                    goto error;
++
++                Py_INCREF(Py_None);
++                Py_INCREF(Py_None);
++                py_tuple = Py_BuildValue(
++                    "(siOOO)",
++                    ifname,
++                    family,
++                    py_address,
++                    Py_None,
++                    Py_None
++                );
++
++                if (! py_tuple)
++                    goto error;
++                if (PyList_Append(py_retlist, py_tuple))
++                    goto error;
++                Py_DECREF(py_tuple);
++                Py_DECREF(py_address);
++
++                pUnicast = pUnicast->Next;
++            }
++        }
++
++        pCurrAddresses = pCurrAddresses->Next;
++    }
++
++    free(pAddresses);
++    return py_retlist;
++
++error:
++    if (pAddresses)
++        free(pAddresses);
++    Py_DECREF(py_retlist);
++    Py_XDECREF(py_tuple);
++    Py_XDECREF(py_address);
++    return NULL;
++}
++
++
++/*
++ * Provides stats about NIC interfaces installed on the system.
++ * TODO: get 'duplex' (currently it's hard coded to '2', aka
++         'full duplex')
++ */
++static PyObject *
++psutil_net_if_stats(PyObject *self, PyObject *args)
++{
++    int i;
++    DWORD dwSize = 0;
++    DWORD dwRetVal = 0;
++    MIB_IFTABLE *pIfTable;
++    MIB_IFROW *pIfRow;
++    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
++    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
++    char friendly_name[MAX_PATH];
++    char descr[MAX_PATH];
++    int ifname_found;
++
++    PyObject *py_retdict = PyDict_New();
++    PyObject *py_ifc_info = NULL;
++    PyObject *py_is_up = NULL;
++
++    if (py_retdict == NULL)
++        return NULL;
++
++    pAddresses = psutil_get_nic_addresses();
++    if (pAddresses == NULL)
++        goto error;
++
++    pIfTable = (MIB_IFTABLE *) malloc(sizeof (MIB_IFTABLE));
++    if (pIfTable == NULL) {
++        PyErr_NoMemory();
++        goto error;
++    }
++    dwSize = sizeof(MIB_IFTABLE);
++    if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
++        free(pIfTable);
++        pIfTable = (MIB_IFTABLE *) malloc(dwSize);
++        if (pIfTable == NULL) {
++            PyErr_NoMemory();
++            goto error;
++        }
++    }
++    // Make a second call to GetIfTable to get the actual
++    // data we want.
++    if ((dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE)) != NO_ERROR) {
++        PyErr_SetString(PyExc_RuntimeError, "GetIfTable() failed");
++        goto error;
++    }
++
++    for (i = 0; i < (int) pIfTable->dwNumEntries; i++) {
++        pIfRow = (MIB_IFROW *) & pIfTable->table[i];
++
++        // GetIfTable is not able to give us NIC with "friendly names"
++        // so we determine them via GetAdapterAddresses() which
++        // provides friendly names *and* descriptions and find the
++        // ones that match.
++        ifname_found = 0;
++        pCurrAddresses = pAddresses;
++        while (pCurrAddresses) {
++            sprintf(descr, "%wS", pCurrAddresses->Description);
++            if (lstrcmp(descr, pIfRow->bDescr) == 0) {
++                sprintf(friendly_name, "%wS", pCurrAddresses->FriendlyName);
++                ifname_found = 1;
++                break;
++            }
++            pCurrAddresses = pCurrAddresses->Next;
++        }
++        if (ifname_found == 0) {
++            // Name not found means GetAdapterAddresses() doesn't list
++            // this NIC, only GetIfTable, meaning it's not really a NIC
++            // interface so we skip it.
++            continue;
++        }
++
++        // is up?
++		if((pIfRow->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
++                pIfRow->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) &&
++                pIfRow->dwAdminStatus == 1 ) {
++			py_is_up = Py_True;
++		}
++		else {
++			py_is_up = Py_False;
++		}
++        Py_INCREF(py_is_up);
++
++        py_ifc_info = Py_BuildValue(
++            "(Oikk)",
++            py_is_up,
++            2,  // there's no way to know duplex so let's assume 'full'
++            pIfRow->dwSpeed / 1000000,  // expressed in bytes, we want Mb
++            pIfRow->dwMtu
++        );
++        if (!py_ifc_info)
++            goto error;
++        if (PyDict_SetItemString(py_retdict, friendly_name, py_ifc_info))
++            goto error;
++        Py_DECREF(py_ifc_info);
++    }
++
++    free(pIfTable);
++    free(pAddresses);
++    return py_retdict;
++
++error:
++    Py_XDECREF(py_is_up);
++    Py_XDECREF(py_ifc_info);
++    Py_DECREF(py_retdict);
++    if (pIfTable != NULL)
++        free(pIfTable);
++    if (pAddresses != NULL)
++        free(pAddresses);
++    return NULL;
++}
++
++
++// ------------------------ Python init ---------------------------
++
++static PyMethodDef
++PsutilMethods[] =
++{
++    // --- per-process functions
++
++    {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
++     "Return process cmdline as a list of cmdline arguments"},
++    {"proc_exe", psutil_proc_exe, METH_VARARGS,
++     "Return path of the process executable"},
++    {"proc_name", psutil_proc_name, METH_VARARGS,
++     "Return process name"},
++    {"proc_kill", psutil_proc_kill, METH_VARARGS,
++     "Kill the process identified by the given PID"},
++    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
++     "Return tuple of user/kern time for the given PID"},
++    {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
++     "Return a float indicating the process create time expressed in "
++     "seconds since the epoch"},
++    {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
++     "Return a tuple of process memory information"},
++    {"proc_memory_info_2", psutil_proc_memory_info, METH_VARARGS,
++     "Alternate implementation"},
++    {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
++     "Return process current working directory"},
++    {"proc_suspend", psutil_proc_suspend, METH_VARARGS,
++     "Suspend a process"},
++    {"proc_resume", psutil_proc_resume, METH_VARARGS,
++     "Resume a process"},
++    {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
++     "Return files opened by process"},
++    {"proc_username", psutil_proc_username, METH_VARARGS,
++     "Return the username of a process"},
++    {"proc_threads", psutil_proc_threads, METH_VARARGS,
++     "Return process threads information as a list of tuple"},
++    {"proc_wait", psutil_proc_wait, METH_VARARGS,
++     "Wait for process to terminate and return its exit code."},
++    {"proc_priority_get", psutil_proc_priority_get, METH_VARARGS,
++     "Return process priority."},
++    {"proc_priority_set", psutil_proc_priority_set, METH_VARARGS,
++     "Set process priority."},
++#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
++    {"proc_io_priority_get", psutil_proc_io_priority_get, METH_VARARGS,
++     "Return process IO priority."},
++    {"proc_io_priority_set", psutil_proc_io_priority_set, METH_VARARGS,
++     "Set process IO priority."},
++#endif
++    {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS,
++     "Return process CPU affinity as a bitmask."},
++    {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
++     "Set process CPU affinity."},
++    {"proc_io_counters", psutil_proc_io_counters, METH_VARARGS,
++     "Get process I/O counters."},
++    {"proc_is_suspended", psutil_proc_is_suspended, METH_VARARGS,
++     "Return True if one of the process threads is in a suspended state"},
++    {"proc_num_handles", psutil_proc_num_handles, METH_VARARGS,
++     "Return the number of handles opened by process."},
++    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
++     "Return a list of process's memory mappings"},
++
++    // --- alternative pinfo interface
++    {"proc_info", psutil_proc_info, METH_VARARGS,
++     "Various process information"},
++
++    // --- system-related functions
++    {"pids", psutil_pids, METH_VARARGS,
++     "Returns a list of PIDs currently running on the system"},
++    {"ppid_map", psutil_ppid_map, METH_VARARGS,
++     "Return a {pid:ppid, ...} dict for all running processes"},
++    {"pid_exists", psutil_pid_exists, METH_VARARGS,
++     "Determine if the process exists in the current process list."},
++    {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
++     "Returns the number of logical CPUs on the system"},
++    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
++     "Returns the number of physical CPUs on the system"},
++    {"boot_time", psutil_boot_time, METH_VARARGS,
++     "Return the system boot time expressed in seconds since the epoch."},
++    {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
++     "Return the total amount of physical memory, in bytes"},
++    {"cpu_times", psutil_cpu_times, METH_VARARGS,
++     "Return system cpu times as a list"},
++    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
++     "Return system per-cpu times as a list of tuples"},
++    {"disk_usage", psutil_disk_usage, METH_VARARGS,
++     "Return path's disk total and free as a Python tuple."},
++    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
++     "Return dict of tuples of networks I/O information."},
++    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
++     "Return dict of tuples of disks I/O information."},
++    {"users", psutil_users, METH_VARARGS,
++     "Return a list of currently connected users."},
++    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
++     "Return disk partitions."},
++    {"net_connections", psutil_net_connections, METH_VARARGS,
++     "Return system-wide connections"},
++    {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
++     "Return NICs addresses."},
++    {"net_if_stats", psutil_net_if_stats, METH_VARARGS,
++     "Return NICs stats."},
++
++    // --- windows API bindings
++    {"win32_QueryDosDevice", psutil_win32_QueryDosDevice, METH_VARARGS,
++     "QueryDosDevice binding"},
++
++    {NULL, NULL, 0, NULL}
++};
++
++
++struct module_state {
++    PyObject *error;
++};
++
++#if PY_MAJOR_VERSION >= 3
++#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
++#else
++#define GETSTATE(m) (&_state)
++static struct module_state _state;
++#endif
++
++#if PY_MAJOR_VERSION >= 3
++
++static int psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
++    Py_VISIT(GETSTATE(m)->error);
++    return 0;
++}
++
++static int psutil_windows_clear(PyObject *m) {
++    Py_CLEAR(GETSTATE(m)->error);
++    return 0;
++}
++
++static struct PyModuleDef moduledef = {
++    PyModuleDef_HEAD_INIT,
++    "psutil_windows",
++    NULL,
++    sizeof(struct module_state),
++    PsutilMethods,
++    NULL,
++    psutil_windows_traverse,
++    psutil_windows_clear,
++    NULL
++};
++
++#define INITERROR return NULL
++
++PyMODINIT_FUNC PyInit__psutil_windows(void)
++
++#else
++#define INITERROR return
++void init_psutil_windows(void)
++#endif
++{
++    struct module_state *st = NULL;
++#if PY_MAJOR_VERSION >= 3
++    PyObject *module = PyModule_Create(&moduledef);
++#else
++    PyObject *module = Py_InitModule("_psutil_windows", PsutilMethods);
++#endif
++
++    if (module == NULL) {
++        INITERROR;
++    }
++
++    st = GETSTATE(module);
++    st->error = PyErr_NewException("_psutil_windows.Error", NULL, NULL);
++    if (st->error == NULL) {
++        Py_DECREF(module);
++        INITERROR;
++    }
++
++    PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
++
++    // process status constants
++    // http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx
++    PyModule_AddIntConstant(
++        module, "ABOVE_NORMAL_PRIORITY_CLASS", ABOVE_NORMAL_PRIORITY_CLASS);
++    PyModule_AddIntConstant(
++        module, "BELOW_NORMAL_PRIORITY_CLASS", BELOW_NORMAL_PRIORITY_CLASS);
++    PyModule_AddIntConstant(
++        module, "HIGH_PRIORITY_CLASS", HIGH_PRIORITY_CLASS);
++    PyModule_AddIntConstant(
++        module, "IDLE_PRIORITY_CLASS", IDLE_PRIORITY_CLASS);
++    PyModule_AddIntConstant(
++        module, "NORMAL_PRIORITY_CLASS", NORMAL_PRIORITY_CLASS);
++    PyModule_AddIntConstant(
++        module, "REALTIME_PRIORITY_CLASS", REALTIME_PRIORITY_CLASS);
++    // connection status constants
++    // http://msdn.microsoft.com/en-us/library/cc669305.aspx
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_CLOSED", MIB_TCP_STATE_CLOSED);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_CLOSING", MIB_TCP_STATE_CLOSING);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_CLOSE_WAIT", MIB_TCP_STATE_CLOSE_WAIT);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_LISTEN", MIB_TCP_STATE_LISTEN);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_ESTAB", MIB_TCP_STATE_ESTAB);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_SYN_SENT", MIB_TCP_STATE_SYN_SENT);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_SYN_RCVD", MIB_TCP_STATE_SYN_RCVD);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_FIN_WAIT1", MIB_TCP_STATE_FIN_WAIT1);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_FIN_WAIT2", MIB_TCP_STATE_FIN_WAIT2);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_LAST_ACK", MIB_TCP_STATE_LAST_ACK);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_TIME_WAIT", MIB_TCP_STATE_TIME_WAIT);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_TIME_WAIT", MIB_TCP_STATE_TIME_WAIT);
++    PyModule_AddIntConstant(
++        module, "MIB_TCP_STATE_DELETE_TCB", MIB_TCP_STATE_DELETE_TCB);
++    PyModule_AddIntConstant(
++        module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
++    // ...for internal use in _psutil_windows.py
++    PyModule_AddIntConstant(
++        module, "INFINITE", INFINITE);
++    PyModule_AddIntConstant(
++        module, "ERROR_ACCESS_DENIED", ERROR_ACCESS_DENIED);
++
++    // set SeDebug for the current process
++    psutil_set_se_debug();
++
++#if PY_MAJOR_VERSION >= 3
++    return module;
++#endif
++}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_windows.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_psutil_windows.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include <Python.h>
++#include <windows.h>
++
++// --- per-process functions
++
++static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_info(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_is_suspended(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_kill(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_info_2(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_num_handles(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_priority_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_priority_set(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_resume(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_suspend(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_username(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_wait(PyObject* self, PyObject* args);
++
++#if (PSUTIL_WINVER >= 0x0600)  // Windows Vista
++static PyObject* psutil_proc_io_priority_get(PyObject* self, PyObject* args);
++static PyObject* psutil_proc_io_priority_set(PyObject* self, PyObject* args);
++#endif
++
++// --- system-related functions
++
++static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
++static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
++static PyObject* psutil_disk_usage(PyObject* self, PyObject* args);
++static PyObject* psutil_net_connections(PyObject* self, PyObject* args);
++static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
++static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
++static PyObject* psutil_pid_exists(PyObject* self, PyObject* args);
++static PyObject* psutil_pids(PyObject* self, PyObject* args);
++static PyObject* psutil_ppid_map(PyObject* self, PyObject* args);
++static PyObject* psutil_users(PyObject* self, PyObject* args);
++static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
++static PyObject* psutil_net_if_addrs(PyObject* self, PyObject* args);
++static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
++
++// --- windows API bindings
++
++static PyObject* psutil_win32_QueryDosDevice(PyObject* self, PyObject* args);
++
++// --- internal
++
++int psutil_proc_suspend_or_resume(DWORD pid, int suspend);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/_pswindows.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/_pswindows.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,550 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""Windows platform implementation."""
++
++import errno
++import functools
++import os
++import sys
++from collections import namedtuple
++
++from . import _common
++from . import _psutil_windows as cext
++from ._common import conn_tmap, usage_percent, isfile_strict
++from ._common import sockfam_to_enum, socktype_to_enum
++from ._compat import PY3, xrange, lru_cache, long
++from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS,
++                              BELOW_NORMAL_PRIORITY_CLASS,
++                              HIGH_PRIORITY_CLASS,
++                              IDLE_PRIORITY_CLASS,
++                              NORMAL_PRIORITY_CLASS,
++                              REALTIME_PRIORITY_CLASS)
++
++if sys.version_info >= (3, 4):
++    import enum
++else:
++    enum = None
++
++# process priority constants, import from __init__.py:
++# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
++__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
++                  "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
++                  "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
++                  "CONN_DELETE_TCB",
++                  "AF_LINK",
++                  ]
++
++# --- module level constants (gets pushed up to psutil module)
++
++CONN_DELETE_TCB = "DELETE_TCB"
++WAIT_TIMEOUT = 0x00000102  # 258 in decimal
++ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES,
++                               cext.ERROR_ACCESS_DENIED])
++if enum is None:
++    AF_LINK = -1
++else:
++    AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
++    AF_LINK = AddressFamily.AF_LINK
++
++TCP_STATUSES = {
++    cext.MIB_TCP_STATE_ESTAB: _common.CONN_ESTABLISHED,
++    cext.MIB_TCP_STATE_SYN_SENT: _common.CONN_SYN_SENT,
++    cext.MIB_TCP_STATE_SYN_RCVD: _common.CONN_SYN_RECV,
++    cext.MIB_TCP_STATE_FIN_WAIT1: _common.CONN_FIN_WAIT1,
++    cext.MIB_TCP_STATE_FIN_WAIT2: _common.CONN_FIN_WAIT2,
++    cext.MIB_TCP_STATE_TIME_WAIT: _common.CONN_TIME_WAIT,
++    cext.MIB_TCP_STATE_CLOSED: _common.CONN_CLOSE,
++    cext.MIB_TCP_STATE_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
++    cext.MIB_TCP_STATE_LAST_ACK: _common.CONN_LAST_ACK,
++    cext.MIB_TCP_STATE_LISTEN: _common.CONN_LISTEN,
++    cext.MIB_TCP_STATE_CLOSING: _common.CONN_CLOSING,
++    cext.MIB_TCP_STATE_DELETE_TCB: CONN_DELETE_TCB,
++    cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
++}
++
++if enum is not None:
++    class Priority(enum.IntEnum):
++        ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
++        BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
++        HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
++        IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
++        NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
++        REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
++
++    globals().update(Priority.__members__)
++
++scputimes = namedtuple('scputimes', ['user', 'system', 'idle'])
++svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
++pextmem = namedtuple(
++    'pextmem', ['num_page_faults', 'peak_wset', 'wset', 'peak_paged_pool',
++                'paged_pool', 'peak_nonpaged_pool', 'nonpaged_pool',
++                'pagefile', 'peak_pagefile', 'private'])
++pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss'])
++pmmap_ext = namedtuple(
++    'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
++ntpinfo = namedtuple(
++    'ntpinfo', ['num_handles', 'ctx_switches', 'user_time', 'kernel_time',
++                'create_time', 'num_threads', 'io_rcount', 'io_wcount',
++                'io_rbytes', 'io_wbytes'])
++
++# set later from __init__.py
++NoSuchProcess = None
++AccessDenied = None
++TimeoutExpired = None
++
++
++@lru_cache(maxsize=512)
++def _win32_QueryDosDevice(s):
++    return cext.win32_QueryDosDevice(s)
++
++
++def _convert_raw_path(s):
++    # convert paths using native DOS format like:
++    # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
++    # into: "C:\Windows\systemew\file.txt"
++    if PY3 and not isinstance(s, str):
++        s = s.decode('utf8')
++    rawdrive = '\\'.join(s.split('\\')[:3])
++    driveletter = _win32_QueryDosDevice(rawdrive)
++    return os.path.join(driveletter, s[len(rawdrive):])
++
++
++# --- public functions
++
++
++def virtual_memory():
++    """System virtual memory as a namedtuple."""
++    mem = cext.virtual_mem()
++    totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
++    #
++    total = totphys
++    avail = availphys
++    free = availphys
++    used = total - avail
++    percent = usage_percent((total - avail), total, _round=1)
++    return svmem(total, avail, percent, used, free)
++
++
++def swap_memory():
++    """Swap system memory as a (total, used, free, sin, sout) tuple."""
++    mem = cext.virtual_mem()
++    total = mem[2]
++    free = mem[3]
++    used = total - free
++    percent = usage_percent(used, total, _round=1)
++    return _common.sswap(total, used, free, percent, 0, 0)
++
++
++def disk_usage(path):
++    """Return disk usage associated with path."""
++    try:
++        total, free = cext.disk_usage(path)
++    except WindowsError:
++        if not os.path.exists(path):
++            msg = "No such file or directory: '%s'" % path
++            raise OSError(errno.ENOENT, msg)
++        raise
++    used = total - free
++    percent = usage_percent(used, total, _round=1)
++    return _common.sdiskusage(total, used, free, percent)
++
++
++def disk_partitions(all):
++    """Return disk partitions."""
++    rawlist = cext.disk_partitions(all)
++    return [_common.sdiskpart(*x) for x in rawlist]
++
++
++def cpu_times():
++    """Return system CPU times as a named tuple."""
++    user, system, idle = cext.cpu_times()
++    return scputimes(user, system, idle)
++
++
++def per_cpu_times():
++    """Return system per-CPU times as a list of named tuples."""
++    ret = []
++    for cpu_t in cext.per_cpu_times():
++        user, system, idle = cpu_t
++        item = scputimes(user, system, idle)
++        ret.append(item)
++    return ret
++
++
++def cpu_count_logical():
++    """Return the number of logical CPUs in the system."""
++    return cext.cpu_count_logical()
++
++
++def cpu_count_physical():
++    """Return the number of physical CPUs in the system."""
++    return cext.cpu_count_phys()
++
++
++def boot_time():
++    """The system boot time expressed in seconds since the epoch."""
++    return cext.boot_time()
++
++
++def net_connections(kind, _pid=-1):
++    """Return socket connections.  If pid == -1 return system-wide
++    connections (as opposed to connections opened by one process only).
++    """
++    if kind not in conn_tmap:
++        raise ValueError("invalid %r kind argument; choose between %s"
++                         % (kind, ', '.join([repr(x) for x in conn_tmap])))
++    families, types = conn_tmap[kind]
++    rawlist = cext.net_connections(_pid, families, types)
++    ret = set()
++    for item in rawlist:
++        fd, fam, type, laddr, raddr, status, pid = item
++        status = TCP_STATUSES[status]
++        fam = sockfam_to_enum(fam)
++        type = socktype_to_enum(type)
++        if _pid == -1:
++            nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid)
++        else:
++            nt = _common.pconn(fd, fam, type, laddr, raddr, status)
++        ret.add(nt)
++    return list(ret)
++
++
++def net_if_stats():
++    ret = cext.net_if_stats()
++    for name, items in ret.items():
++        isup, duplex, speed, mtu = items
++        if hasattr(_common, 'NicDuplex'):
++            duplex = _common.NicDuplex(duplex)
++        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
++    return ret
++
++
++def users():
++    """Return currently connected users as a list of namedtuples."""
++    retlist = []
++    rawlist = cext.users()
++    for item in rawlist:
++        user, hostname, tstamp = item
++        nt = _common.suser(user, None, hostname, tstamp)
++        retlist.append(nt)
++    return retlist
++
++
++pids = cext.pids
++pid_exists = cext.pid_exists
++net_io_counters = cext.net_io_counters
++disk_io_counters = cext.disk_io_counters
++ppid_map = cext.ppid_map  # not meant to be public
++net_if_addrs = cext.net_if_addrs
++
++
++def wrap_exceptions(fun):
++    """Decorator which translates bare OSError and WindowsError
++    exceptions into NoSuchProcess and AccessDenied.
++    """
++    @functools.wraps(fun)
++    def wrapper(self, *args, **kwargs):
++        try:
++            return fun(self, *args, **kwargs)
++        except OSError as err:
++            # support for private module import
++            if NoSuchProcess is None or AccessDenied is None:
++                raise
++            if err.errno in ACCESS_DENIED_SET:
++                raise AccessDenied(self.pid, self._name)
++            if err.errno == errno.ESRCH:
++                raise NoSuchProcess(self.pid, self._name)
++            raise
++    return wrapper
++
++
++class Process(object):
++    """Wrapper class around underlying C implementation."""
++
++    __slots__ = ["pid", "_name", "_ppid"]
++
++    def __init__(self, pid):
++        self.pid = pid
++        self._name = None
++        self._ppid = None
++
++    @wrap_exceptions
++    def name(self):
++        """Return process name, which on Windows is always the final
++        part of the executable.
++        """
++        # This is how PIDs 0 and 4 are always represented in taskmgr
++        # and process-hacker.
++        if self.pid == 0:
++            return "System Idle Process"
++        elif self.pid == 4:
++            return "System"
++        else:
++            try:
++                # Note: this will fail with AD for most PIDs owned
++                # by another user but it's faster.
++                return os.path.basename(self.exe())
++            except OSError as err:
++                if err.errno in ACCESS_DENIED_SET:
++                    return cext.proc_name(self.pid)
++                raise
++
++    @wrap_exceptions
++    def exe(self):
++        # Note: os.path.exists(path) may return False even if the file
++        # is there, see:
++        # http://stackoverflow.com/questions/3112546/os-path-exists-lies
++
++        # see https://github.com/giampaolo/psutil/issues/414
++        # see https://github.com/giampaolo/psutil/issues/528
++        if self.pid in (0, 4):
++            raise AccessDenied(self.pid, self._name)
++        return _convert_raw_path(cext.proc_exe(self.pid))
++
++    @wrap_exceptions
++    def cmdline(self):
++        return cext.proc_cmdline(self.pid)
++
++    def ppid(self):
++        try:
++            return ppid_map()[self.pid]
++        except KeyError:
++            raise NoSuchProcess(self.pid, self._name)
++
++    def _get_raw_meminfo(self):
++        try:
++            return cext.proc_memory_info(self.pid)
++        except OSError as err:
++            if err.errno in ACCESS_DENIED_SET:
++                # TODO: the C ext can probably be refactored in order
++                # to get this from cext.proc_info()
++                return cext.proc_memory_info_2(self.pid)
++            raise
++
++    @wrap_exceptions
++    def memory_info(self):
++        # on Windows RSS == WorkingSetSize and VSM == PagefileUsage
++        # fields of PROCESS_MEMORY_COUNTERS struct:
++        # http://msdn.microsoft.com/en-us/library/windows/desktop/
++        #     ms684877(v=vs.85).aspx
++        t = self._get_raw_meminfo()
++        return _common.pmem(t[2], t[7])
++
++    @wrap_exceptions
++    def memory_info_ex(self):
++        return pextmem(*self._get_raw_meminfo())
++
++    def memory_maps(self):
++        try:
++            raw = cext.proc_memory_maps(self.pid)
++        except OSError as err:
++            # XXX - can't use wrap_exceptions decorator as we're
++            # returning a generator; probably needs refactoring.
++            if err.errno in ACCESS_DENIED_SET:
++                raise AccessDenied(self.pid, self._name)
++            if err.errno == errno.ESRCH:
++                raise NoSuchProcess(self.pid, self._name)
++            raise
++        else:
++            for addr, perm, path, rss in raw:
++                path = _convert_raw_path(path)
++                addr = hex(addr)
++                yield (addr, perm, path, rss)
++
++    @wrap_exceptions
++    def kill(self):
++        return cext.proc_kill(self.pid)
++
++    @wrap_exceptions
++    def wait(self, timeout=None):
++        if timeout is None:
++            timeout = cext.INFINITE
++        else:
++            # WaitForSingleObject() expects time in milliseconds
++            timeout = int(timeout * 1000)
++        ret = cext.proc_wait(self.pid, timeout)
++        if ret == WAIT_TIMEOUT:
++            # support for private module import
++            if TimeoutExpired is None:
++                raise RuntimeError("timeout expired")
++            raise TimeoutExpired(timeout, self.pid, self._name)
++        return ret
++
++    @wrap_exceptions
++    def username(self):
++        if self.pid in (0, 4):
++            return 'NT AUTHORITY\\SYSTEM'
++        return cext.proc_username(self.pid)
++
++    @wrap_exceptions
++    def create_time(self):
++        # special case for kernel process PIDs; return system boot time
++        if self.pid in (0, 4):
++            return boot_time()
++        try:
++            return cext.proc_create_time(self.pid)
++        except OSError as err:
++            if err.errno in ACCESS_DENIED_SET:
++                return ntpinfo(*cext.proc_info(self.pid)).create_time
++            raise
++
++    @wrap_exceptions
++    def num_threads(self):
++        return ntpinfo(*cext.proc_info(self.pid)).num_threads
++
++    @wrap_exceptions
++    def threads(self):
++        rawlist = cext.proc_threads(self.pid)
++        retlist = []
++        for thread_id, utime, stime in rawlist:
++            ntuple = _common.pthread(thread_id, utime, stime)
++            retlist.append(ntuple)
++        return retlist
++
++    @wrap_exceptions
++    def cpu_times(self):
++        try:
++            ret = cext.proc_cpu_times(self.pid)
++        except OSError as err:
++            if err.errno in ACCESS_DENIED_SET:
++                nt = ntpinfo(*cext.proc_info(self.pid))
++                ret = (nt.user_time, nt.kernel_time)
++            else:
++                raise
++        return _common.pcputimes(*ret)
++
++    @wrap_exceptions
++    def suspend(self):
++        return cext.proc_suspend(self.pid)
++
++    @wrap_exceptions
++    def resume(self):
++        return cext.proc_resume(self.pid)
++
++    @wrap_exceptions
++    def cwd(self):
++        if self.pid in (0, 4):
++            raise AccessDenied(self.pid, self._name)
++        # return a normalized pathname since the native C function appends
++        # "\\" at the and of the path
++        path = cext.proc_cwd(self.pid)
++        return os.path.normpath(path)
++
++    @wrap_exceptions
++    def open_files(self):
++        if self.pid in (0, 4):
++            return []
++        retlist = []
++        # Filenames come in in native format like:
++        # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
++        # Convert the first part in the corresponding drive letter
++        # (e.g. "C:\") by using Windows's QueryDosDevice()
++        raw_file_names = cext.proc_open_files(self.pid)
++        for file in raw_file_names:
++            file = _convert_raw_path(file)
++            if isfile_strict(file) and file not in retlist:
++                ntuple = _common.popenfile(file, -1)
++                retlist.append(ntuple)
++        return retlist
++
++    @wrap_exceptions
++    def connections(self, kind='inet'):
++        return net_connections(kind, _pid=self.pid)
++
++    @wrap_exceptions
++    def nice_get(self):
++        value = cext.proc_priority_get(self.pid)
++        if enum is not None:
++            value = Priority(value)
++        return value
++
++    @wrap_exceptions
++    def nice_set(self, value):
++        return cext.proc_priority_set(self.pid, value)
++
++    # available on Windows >= Vista
++    if hasattr(cext, "proc_io_priority_get"):
++        @wrap_exceptions
++        def ionice_get(self):
++            return cext.proc_io_priority_get(self.pid)
++
++        @wrap_exceptions
++        def ionice_set(self, value, _):
++            if _:
++                raise TypeError("set_proc_ionice() on Windows takes only "
++                                "1 argument (2 given)")
++            if value not in (2, 1, 0):
++                raise ValueError("value must be 2 (normal), 1 (low) or 0 "
++                                 "(very low); got %r" % value)
++            return cext.proc_io_priority_set(self.pid, value)
++
++    @wrap_exceptions
++    def io_counters(self):
++        try:
++            ret = cext.proc_io_counters(self.pid)
++        except OSError as err:
++            if err.errno in ACCESS_DENIED_SET:
++                nt = ntpinfo(*cext.proc_info(self.pid))
++                ret = (nt.io_rcount, nt.io_wcount, nt.io_rbytes, nt.io_wbytes)
++            else:
++                raise
++        return _common.pio(*ret)
++
++    @wrap_exceptions
++    def status(self):
++        suspended = cext.proc_is_suspended(self.pid)
++        if suspended:
++            return _common.STATUS_STOPPED
++        else:
++            return _common.STATUS_RUNNING
++
++    @wrap_exceptions
++    def cpu_affinity_get(self):
++        def from_bitmask(x):
++            return [i for i in xrange(64) if (1 << i) & x]
++        bitmask = cext.proc_cpu_affinity_get(self.pid)
++        return from_bitmask(bitmask)
++
++    @wrap_exceptions
++    def cpu_affinity_set(self, value):
++        def to_bitmask(l):
++            if not l:
++                raise ValueError("invalid argument %r" % l)
++            out = 0
++            for b in l:
++                out |= 2 ** b
++            return out
++
++        # SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
++        # is returned for an invalid CPU but this seems not to be true,
++        # therefore we check CPUs validy beforehand.
++        allcpus = list(range(len(per_cpu_times())))
++        for cpu in value:
++            if cpu not in allcpus:
++                if not isinstance(cpu, (int, long)):
++                    raise TypeError(
++                        "invalid CPU %r; an integer is required" % cpu)
++                else:
++                    raise ValueError("invalid CPU %r" % cpu)
++
++        bitmask = to_bitmask(value)
++        cext.proc_cpu_affinity_set(self.pid, bitmask)
++
++    @wrap_exceptions
++    def num_handles(self):
++        try:
++            return cext.proc_num_handles(self.pid)
++        except OSError as err:
++            if err.errno in ACCESS_DENIED_SET:
++                return ntpinfo(*cext.proc_info(self.pid)).num_handles
++            raise
++
++    @wrap_exceptions
++    def num_ctx_switches(self):
++        ctx_switches = ntpinfo(*cext.proc_info(self.pid)).ctx_switches
++        # only voluntary ctx switches are supported
++        return _common.pctxsw(ctx_switches, 0)
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/bsd/process_info.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/bsd/process_info.c	2015-06-17 19:33:33.000000000 -0700
+@@ -3,10 +3,11 @@
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+- * Helper functions related to fetching process information. Used by _psutil_bsd
+- * module methods.
++ * Helper functions related to fetching process information.
++ * Used by _psutil_bsd module methods.
+  */
+ 
++
+ #include <Python.h>
+ #include <assert.h>
+ #include <errno.h>
+@@ -35,7 +36,7 @@
+ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount)
+ {
+     int err;
+-    struct kinfo_proc * result;
++    struct kinfo_proc *result;
+     int done;
+     static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
+     // Declaring name as const requires us to cast it when passing it to
+@@ -82,7 +83,7 @@
+         // error, toss away our buffer and start again.
+         if (err == 0) {
+             err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
+-                          result, &length, NULL, 0);
++                         result, &length, NULL, 0);
+             if (err == -1)
+                 err = errno;
+             if (err == 0) {
+@@ -114,7 +115,7 @@
+ char
+ *psutil_get_cmd_path(long pid, size_t *pathsize)
+ {
+-    int  mib[4];
++    int mib[4];
+     char *path;
+     size_t size = 0;
+ 
+@@ -127,9 +128,8 @@
+     mib[3] = pid;
+ 
+     // call with a null buffer first to determine if we need a buffer
+-    if (sysctl(mib, 4, NULL, &size, NULL, 0) == -1) {
++    if (sysctl(mib, 4, NULL, &size, NULL, 0) == -1)
+         return NULL;
+-    }
+ 
+     path = malloc(size);
+     if (path == NULL) {
+@@ -140,7 +140,7 @@
+     *pathsize = size;
+     if (sysctl(mib, 4, path, &size, NULL, 0) == -1) {
+         free(path);
+-        return NULL;       /* Insufficient privileges */
++        return NULL;       // Insufficient privileges
+     }
+ 
+     return path;
+@@ -167,7 +167,7 @@
+     size_t size = sizeof(argmax);
+     char *procargs = NULL;
+ 
+-    /* Get the maximum process arguments size. */
++    // Get the maximum process arguments size.
+     mib[0] = CTL_KERN;
+     mib[1] = KERN_ARGMAX;
+ 
+@@ -175,7 +175,7 @@
+     if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
+         return NULL;
+ 
+-    /* Allocate space for the arguments. */
++    // Allocate space for the arguments.
+     procargs = (char *)malloc(argmax);
+     if (procargs == NULL) {
+         PyErr_NoMemory();
+@@ -193,7 +193,7 @@
+     size = argmax;
+     if (sysctl(mib, 4, procargs, &size, NULL, 0) == -1) {
+         free(procargs);
+-        return NULL;       /* Insufficient privileges */
++        return NULL;       // Insufficient privileges
+     }
+ 
+     // return string and set the length of arguments
+@@ -202,8 +202,8 @@
+ }
+ 
+ 
+-/* returns the command line as a python list object */
+-PyObject*
++// returns the command line as a python list object
++PyObject *
+ psutil_get_arg_list(long pid)
+ {
+     char *argstr = NULL;
+@@ -212,20 +212,17 @@
+     PyObject *retlist = Py_BuildValue("[]");
+     PyObject *item = NULL;
+ 
+-    if (pid < 0) {
++    if (pid < 0)
+         return retlist;
+-    }
+-
+     argstr = psutil_get_cmd_args(pid, &argsize);
+-    if (argstr == NULL) {
++    if (argstr == NULL)
+         goto error;
+-    }
+ 
+     // args are returned as a flattened string with \0 separators between
+     // arguments add each string to the list then step forward to the next
+     // separator
+     if (argsize > 0) {
+-        while(pos < argsize) {
++        while (pos < argsize) {
+             item = Py_BuildValue("s", &argstr[pos]);
+             if (!item)
+                 goto error;
+@@ -255,30 +252,14 @@
+ psutil_pid_exists(long pid)
+ {
+     int kill_ret;
+-    if (pid < 0) {
+-        return 0;
+-    }
+ 
++    if (pid < 0)
++        return 0;
+     // if kill returns success of permission denied we know it's a valid PID
+     kill_ret = kill(pid , 0);
+-    if ((0 == kill_ret) || (EPERM == errno)) {
++    if ((0 == kill_ret) || (EPERM == errno))
+         return 1;
+-    }
+-
+     // otherwise return 0 for PID not found
+     return 0;
+ }
+ 
+-
+-/*
+- * Set exception to AccessDenied if pid exists else NoSuchProcess.
+- */
+-int
+-psutil_raise_ad_or_nsp(pid) {
+-    if (psutil_pid_exists(pid) == 0) {
+-        NoSuchProcess();
+-    }
+-    else {
+-        AccessDenied();
+-    }
+-}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/bsd/process_info.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/bsd/process_info.h	2015-06-17 19:33:33.000000000 -0700
+@@ -2,17 +2,14 @@
+  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * Helper functions related to fetching process information. Used by _psutil_bsd
+- * module methods.
+  */
+ 
+ #include <Python.h>
+ 
+ typedef struct kinfo_proc kinfo_proc;
+ 
+-int  psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
+ char *psutil_get_cmd_args(long pid, size_t *argsize);
+ char *psutil_get_cmd_path(long pid, size_t *pathsize);
+-int  psutil_pid_exists(long pid);
++int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
++int psutil_pid_exists(long pid);
+ PyObject* psutil_get_arg_list(long pid);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/ntextapi.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/ntextapi.h	1969-12-31 16:00:00.000000000 -0800
+@@ -1,306 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- */
+-
+-typedef enum _KTHREAD_STATE
+-{
+-    Initialized,
+-    Ready,
+-    Running,
+-    Standby,
+-    Terminated,
+-    Waiting,
+-    Transition,
+-    DeferredReady,
+-    GateWait,
+-    MaximumThreadState
+-} KTHREAD_STATE, *PKTHREAD_STATE;
+-
+-typedef enum _KWAIT_REASON
+-{
+-    Executive = 0,
+-    FreePage = 1,
+-    PageIn = 2,
+-    PoolAllocation = 3,
+-    DelayExecution = 4,
+-    Suspended = 5,
+-    UserRequest = 6,
+-    WrExecutive = 7,
+-    WrFreePage = 8,
+-    WrPageIn = 9,
+-    WrPoolAllocation = 10,
+-    WrDelayExecution = 11,
+-    WrSuspended = 12,
+-    WrUserRequest = 13,
+-    WrEventPair = 14,
+-    WrQueue = 15,
+-    WrLpcReceive = 16,
+-    WrLpcReply = 17,
+-    WrVirtualMemory = 18,
+-    WrPageOut = 19,
+-    WrRendezvous = 20,
+-    Spare2 = 21,
+-    Spare3 = 22,
+-    Spare4 = 23,
+-    Spare5 = 24,
+-    WrCalloutStack = 25,
+-    WrKernel = 26,
+-    WrResource = 27,
+-    WrPushLock = 28,
+-    WrMutex = 29,
+-    WrQuantumEnd = 30,
+-    WrDispatchInt = 31,
+-    WrPreempted = 32,
+-    WrYieldExecution = 33,
+-    WrFastMutex = 34,
+-    WrGuardedMutex = 35,
+-    WrRundown = 36,
+-    MaximumWaitReason = 37
+-} KWAIT_REASON, *PKWAIT_REASON;
+-
+-
+-typedef struct _CLIENT_ID
+-{
+-    HANDLE UniqueProcess;
+-    HANDLE UniqueThread;
+-} CLIENT_ID, *PCLIENT_ID;
+-
+-
+-typedef struct _UNICODE_STRING {
+-    USHORT Length;
+-    USHORT MaximumLength;
+-    PWSTR Buffer;
+-} UNICODE_STRING, *PUNICODE_STRING;
+-
+-
+-typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
+-{
+-    LARGE_INTEGER BootTime;
+-    LARGE_INTEGER CurrentTime;
+-    LARGE_INTEGER TimeZoneBias;
+-    ULONG TimeZoneId;
+-    ULONG Reserved;
+-    ULONGLONG BootTimeBias;
+-    ULONGLONG SleepTimeBias;
+-} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
+-
+-typedef struct _SYSTEM_THREAD_INFORMATION
+-{
+-    LARGE_INTEGER KernelTime;
+-    LARGE_INTEGER UserTime;
+-    LARGE_INTEGER CreateTime;
+-    ULONG WaitTime;
+-    PVOID StartAddress;
+-    CLIENT_ID ClientId;
+-    LONG Priority;
+-    LONG BasePriority;
+-    ULONG ContextSwitches;
+-    ULONG ThreadState;
+-    KWAIT_REASON WaitReason;
+-} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
+-
+-typedef struct _TEB *PTEB;
+-
+-// private
+-typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION
+-{
+-    SYSTEM_THREAD_INFORMATION ThreadInfo;
+-    PVOID StackBase;
+-    PVOID StackLimit;
+-    PVOID Win32StartAddress;
+-    PTEB TebBase;
+-    ULONG_PTR Reserved2;
+-    ULONG_PTR Reserved3;
+-    ULONG_PTR Reserved4;
+-} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
+-
+-typedef struct _SYSTEM_PROCESS_INFORMATION
+-{
+-    ULONG NextEntryOffset;
+-    ULONG NumberOfThreads;
+-    LARGE_INTEGER SpareLi1;
+-    LARGE_INTEGER SpareLi2;
+-    LARGE_INTEGER SpareLi3;
+-    LARGE_INTEGER CreateTime;
+-    LARGE_INTEGER UserTime;
+-    LARGE_INTEGER KernelTime;
+-    UNICODE_STRING ImageName;
+-    LONG BasePriority;
+-    HANDLE UniqueProcessId;
+-    HANDLE InheritedFromUniqueProcessId;
+-    ULONG HandleCount;
+-    ULONG SessionId;
+-    ULONG_PTR PageDirectoryBase;
+-    SIZE_T PeakVirtualSize;
+-    SIZE_T VirtualSize;
+-    DWORD PageFaultCount;
+-    SIZE_T PeakWorkingSetSize;
+-    SIZE_T WorkingSetSize;
+-    SIZE_T QuotaPeakPagedPoolUsage;
+-    SIZE_T QuotaPagedPoolUsage;
+-    SIZE_T QuotaPeakNonPagedPoolUsage;
+-    SIZE_T QuotaNonPagedPoolUsage;
+-    SIZE_T PagefileUsage;
+-    SIZE_T PeakPagefileUsage;
+-    SIZE_T PrivatePageCount;
+-    LARGE_INTEGER ReadOperationCount;
+-    LARGE_INTEGER WriteOperationCount;
+-    LARGE_INTEGER OtherOperationCount;
+-    LARGE_INTEGER ReadTransferCount;
+-    LARGE_INTEGER WriteTransferCount;
+-    LARGE_INTEGER OtherTransferCount;
+-    SYSTEM_THREAD_INFORMATION Threads[1];
+-} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
+-
+-
+-// structures and enums from winternl.h (not available under mingw)
+-typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
+-    LARGE_INTEGER IdleTime;
+-    LARGE_INTEGER KernelTime;
+-    LARGE_INTEGER UserTime;
+-    LARGE_INTEGER Reserved1[2];
+-    ULONG Reserved2;
+-} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
+-
+-
+-typedef enum _SYSTEM_INFORMATION_CLASS {
+-    SystemBasicInformation = 0,
+-    SystemPerformanceInformation = 2,
+-    SystemTimeOfDayInformation = 3,
+-    SystemProcessInformation = 5,
+-    SystemProcessorPerformanceInformation = 8,
+-    SystemInterruptInformation = 23,
+-    SystemExceptionInformation = 33,
+-    SystemRegistryQuotaInformation = 37,
+-    SystemLookasideInformation = 45
+-} SYSTEM_INFORMATION_CLASS;
+-
+-
+-// ================================================
+-// get_system_users support ()
+-// ================================================
+-
+-typedef struct _WINSTATION_INFO {
+-    BYTE Reserved1[72];
+-    ULONG SessionId;
+-    BYTE Reserved2[4];
+-    FILETIME ConnectTime;
+-    FILETIME DisconnectTime;
+-    FILETIME LastInputTime;
+-    FILETIME LoginTime;
+-    BYTE Reserved3[1096];
+-    FILETIME CurrentTime;
+-} WINSTATION_INFO, *PWINSTATION_INFO;
+-
+-typedef enum _WINSTATIONINFOCLASS {
+-     WinStationInformation = 8
+-} WINSTATIONINFOCLASS;
+-
+-typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
+-                 (HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
+-
+-typedef struct _WINSTATIONINFORMATIONW {
+-    BYTE Reserved2[70];
+-    ULONG LogonId;
+-    BYTE Reserved3[1140];
+-} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
+-
+-// start mingw support:
+-// http://www.koders.com/c/fid7C02CAE627C526914CDEB427405B51DF393A5EFA.aspx
+-#ifndef _INC_WTSAPI
+-typedef struct _WTS_CLIENT_ADDRESS {
+-    DWORD AddressFamily;  // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
+-    BYTE  Address[20];    // client network address
+-} WTS_CLIENT_ADDRESS, * PWTS_CLIENT_ADDRESS;
+-
+-HANDLE
+-WINAPI
+-WTSOpenServerA(
+-    IN LPSTR pServerName
+-    );
+-
+-VOID
+-WINAPI
+-WTSCloseServer(
+-    IN HANDLE hServer
+-    );
+-#endif
+-// end mingw support:
+-
+-/*
+- * NtQueryInformationProcess code taken from
+- * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
+- * typedefs needed to compile against ntdll functions not exposted in the API
+- */
+-typedef LONG NTSTATUS;
+-
+-typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
+-    HANDLE ProcessHandle,
+-    DWORD ProcessInformationClass,
+-    PVOID ProcessInformation,
+-    DWORD ProcessInformationLength,
+-    PDWORD ReturnLength
+-    );
+-
+-typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
+-    HANDLE ProcessHandle,
+-    DWORD ProcessInformationClass,
+-    PVOID ProcessInformation,
+-    DWORD ProcessInformationLength
+-);
+-
+-typedef struct _PROCESS_BASIC_INFORMATION
+-{
+-    PVOID Reserved1;
+-    PVOID PebBaseAddress;
+-    PVOID Reserved2[2];
+-    ULONG_PTR UniqueProcessId;
+-    PVOID Reserved3;
+-} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
+-
+-
+-typedef enum _PROCESSINFOCLASS {
+-    ProcessBasicInformation,
+-    ProcessQuotaLimits,
+-    ProcessIoCounters,
+-    ProcessVmCounters,
+-    ProcessTimes,
+-    ProcessBasePriority,
+-    ProcessRaisePriority,
+-    ProcessDebugPort,
+-    ProcessExceptionPort,
+-    ProcessAccessToken,
+-    ProcessLdtInformation,
+-    ProcessLdtSize,
+-    ProcessDefaultHardErrorMode,
+-    ProcessIoPortHandlers,
+-    ProcessPooledUsageAndLimits,
+-    ProcessWorkingSetWatch,
+-    ProcessUserModeIOPL,
+-    ProcessEnableAlignmentFaultFixup,
+-    ProcessPriorityClass,
+-    ProcessWx86Information,
+-    ProcessHandleCount,
+-    ProcessAffinityMask,
+-    ProcessPriorityBoost,
+-    ProcessDeviceMap,
+-    ProcessSessionInformation,
+-    ProcessForegroundInformation,
+-    ProcessWow64Information,
+-    /* added after XP+ */
+-    ProcessImageFileName,
+-    ProcessLUIDDeviceMapsEnabled,
+-    ProcessBreakOnTermination,
+-    ProcessDebugObjectHandle,
+-    ProcessDebugFlags,
+-    ProcessHandleTracing,
+-    ProcessIoPriority,
+-    ProcessExecuteFlags,
+-    ProcessResourceManagement,
+-    ProcessCookie,
+-    ProcessImageInformation,
+-    MaxProcessInfoClass
+-} PROCESSINFOCLASS;
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_handles.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_handles.c	1969-12-31 16:00:00.000000000 -0800
+@@ -1,326 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- */
+-
+-#ifndef UNICODE
+-#define UNICODE
+-#endif
+-
+-#include <Python.h>
+-#include <windows.h>
+-#include <stdio.h>
+-#include "process_handles.h"
+-
+-#ifndef NT_SUCCESS
+-    #define NT_SUCCESS(x) ((x) >= 0)
+-#endif
+-#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
+-
+-#define SystemHandleInformation 16
+-#define ObjectBasicInformation 0
+-#define ObjectNameInformation 1
+-#define ObjectTypeInformation 2
+-
+-
+-typedef LONG NTSTATUS;
+-
+-typedef struct _UNICODE_STRING {
+-  USHORT  Length;
+-  USHORT  MaximumLength;
+-  PWSTR  Buffer;
+-} UNICODE_STRING, *PUNICODE_STRING;
+-
+-typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
+-    ULONG SystemInformationClass,
+-    PVOID SystemInformation,
+-    ULONG SystemInformationLength,
+-    PULONG ReturnLength
+-    );
+-
+-typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
+-    HANDLE SourceProcessHandle,
+-    HANDLE SourceHandle,
+-    HANDLE TargetProcessHandle,
+-    PHANDLE TargetHandle,
+-    ACCESS_MASK DesiredAccess,
+-    ULONG Attributes,
+-    ULONG Options
+-    );
+-
+-typedef NTSTATUS (NTAPI *_NtQueryObject)(
+-    HANDLE ObjectHandle,
+-    ULONG ObjectInformationClass,
+-    PVOID ObjectInformation,
+-    ULONG ObjectInformationLength,
+-    PULONG ReturnLength
+-    );
+-
+-typedef struct _SYSTEM_HANDLE
+-{
+-    ULONG ProcessId;
+-    BYTE ObjectTypeNumber;
+-    BYTE Flags;
+-    USHORT Handle;
+-    PVOID Object;
+-    ACCESS_MASK GrantedAccess;
+-} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
+-
+-typedef struct _SYSTEM_HANDLE_INFORMATION
+-{
+-    ULONG HandleCount;
+-    SYSTEM_HANDLE Handles[1];
+-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+-
+-typedef enum _POOL_TYPE
+-{
+-    NonPagedPool,
+-    PagedPool,
+-    NonPagedPoolMustSucceed,
+-    DontUseThisType,
+-    NonPagedPoolCacheAligned,
+-    PagedPoolCacheAligned,
+-    NonPagedPoolCacheAlignedMustS
+-} POOL_TYPE, *PPOOL_TYPE;
+-
+-typedef struct _OBJECT_TYPE_INFORMATION
+-{
+-    UNICODE_STRING Name;
+-    ULONG TotalNumberOfObjects;
+-    ULONG TotalNumberOfHandles;
+-    ULONG TotalPagedPoolUsage;
+-    ULONG TotalNonPagedPoolUsage;
+-    ULONG TotalNamePoolUsage;
+-    ULONG TotalHandleTableUsage;
+-    ULONG HighWaterNumberOfObjects;
+-    ULONG HighWaterNumberOfHandles;
+-    ULONG HighWaterPagedPoolUsage;
+-    ULONG HighWaterNonPagedPoolUsage;
+-    ULONG HighWaterNamePoolUsage;
+-    ULONG HighWaterHandleTableUsage;
+-    ULONG InvalidAttributes;
+-    GENERIC_MAPPING GenericMapping;
+-    ULONG ValidAccess;
+-    BOOLEAN SecurityRequired;
+-    BOOLEAN MaintainHandleCount;
+-    USHORT MaintainTypeList;
+-    POOL_TYPE PoolType;
+-    ULONG PagedPoolUsage;
+-    ULONG NonPagedPoolUsage;
+-} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+-
+-PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
+-{
+-    return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
+-}
+-
+-
+-PyObject*
+-psutil_get_open_files(long pid, HANDLE processHandle)
+-{
+-    _NtQuerySystemInformation NtQuerySystemInformation =
+-        GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
+-    _NtDuplicateObject NtDuplicateObject =
+-        GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
+-    _NtQueryObject NtQueryObject =
+-        GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
+-
+-    NTSTATUS                    status;
+-    PSYSTEM_HANDLE_INFORMATION  handleInfo;
+-    ULONG                       handleInfoSize = 0x10000;
+-
+-    ULONG                       i;
+-    ULONG                       fileNameLength;
+-    PyObject                    *filesList = Py_BuildValue("[]");
+-    PyObject                    *arg = NULL;
+-    PyObject                    *fileFromWchar = NULL;
+-
+-    if (filesList == NULL)
+-        return NULL;
+-
+-    handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
+-    if (handleInfo == NULL) {
+-        Py_DECREF(filesList);
+-        PyErr_NoMemory();
+-        return NULL;
+-    }
+-
+-    /* NtQuerySystemInformation won't give us the correct buffer size,
+-       so we guess by doubling the buffer size. */
+-    while ((status = NtQuerySystemInformation(
+-        SystemHandleInformation,
+-        handleInfo,
+-        handleInfoSize,
+-        NULL
+-        )) == STATUS_INFO_LENGTH_MISMATCH)
+-    {
+-        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
+-    }
+-
+-    /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
+-    if (!NT_SUCCESS(status)) {
+-        //printf("NtQuerySystemInformation failed!\n");
+-        Py_DECREF(filesList);
+-        free(handleInfo);
+-        return NULL;
+-    }
+-
+-    for (i = 0; i < handleInfo->HandleCount; i++)
+-    {
+-        SYSTEM_HANDLE            handle = handleInfo->Handles[i];
+-        HANDLE                   dupHandle = NULL;
+-        POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
+-        PVOID                    objectNameInfo;
+-        UNICODE_STRING           objectName;
+-        ULONG                    returnLength;
+-        fileFromWchar = NULL;
+-        arg = NULL;
+-
+-        /* Check if this handle belongs to the PID the user specified. */
+-        if (handle.ProcessId != pid)
+-            continue;
+-
+-        /* Skip handles with the following access codes as the next call
+-           to NtDuplicateObject() or NtQueryObject() might hang forever. */
+-        if((handle.GrantedAccess == 0x0012019f)
+-        || (handle.GrantedAccess == 0x001a019f)
+-        || (handle.GrantedAccess == 0x00120189)
+-        || (handle.GrantedAccess == 0x00100000)) {
+-            continue;
+-        }
+-
+-        /* Duplicate the handle so we can query it. */
+-        if (!NT_SUCCESS(NtDuplicateObject(
+-            processHandle,
+-            handle.Handle,
+-            GetCurrentProcess(),
+-            &dupHandle,
+-            0,
+-            0,
+-            0
+-            )))
+-        {
+-            //printf("[%#x] Error!\n", handle.Handle);
+-            continue;
+-        }
+-
+-        /* Query the object type. */
+-        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
+-        if (!NT_SUCCESS(NtQueryObject(
+-            dupHandle,
+-            ObjectTypeInformation,
+-            objectTypeInfo,
+-            0x1000,
+-            NULL
+-            )))
+-        {
+-            //printf("[%#x] Error!\n", handle.Handle);
+-            free(objectTypeInfo);
+-            CloseHandle(dupHandle);
+-            continue;
+-        }
+-
+-        objectNameInfo = malloc(0x1000);
+-        if (!NT_SUCCESS(NtQueryObject(
+-            dupHandle,
+-            ObjectNameInformation,
+-            objectNameInfo,
+-            0x1000,
+-            &returnLength
+-            )))
+-        {
+-            /* Reallocate the buffer and try again. */
+-            objectNameInfo = realloc(objectNameInfo, returnLength);
+-            if (!NT_SUCCESS(NtQueryObject(
+-                dupHandle,
+-                ObjectNameInformation,
+-                objectNameInfo,
+-                returnLength,
+-                NULL
+-                )))
+-            {
+-                /* We have the type name, so just display that.*/
+-                /*
+-                printf(
+-                    "[%#x] %.*S: (could not get name)\n",
+-                    handle.Handle,
+-                    objectTypeInfo->Name.Length / 2,
+-                    objectTypeInfo->Name.Buffer
+-                    );
+-                */
+-                free(objectTypeInfo);
+-                free(objectNameInfo);
+-                CloseHandle(dupHandle);
+-                continue;
+-
+-            }
+-        }
+-
+-        /* Cast our buffer into an UNICODE_STRING. */
+-        objectName = *(PUNICODE_STRING)objectNameInfo;
+-
+-        /* Print the information! */
+-        if (objectName.Length)
+-        {
+-            /* The object has a name.  Make sure it is a file otherwise
+-               ignore it */
+-            fileNameLength = objectName.Length / 2;
+-            if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
+-                //printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
+-                fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
+-                                                       fileNameLength);
+-                if (fileFromWchar == NULL)
+-                    goto error_py_fun;
+-                #if PY_MAJOR_VERSION >= 3
+-                    arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar));
+-                #else
+-                    arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar));
+-                #endif
+-                if (!arg)
+-                    goto error_py_fun;
+-                Py_XDECREF(fileFromWchar);
+-                fileFromWchar = NULL;
+-                if (PyList_Append(filesList, arg))
+-                    goto error_py_fun;
+-                Py_XDECREF(arg);
+-            }
+-            /*
+-            printf(
+-                "[%#x] %.*S: %.*S\n",
+-                handle.Handle,
+-                objectTypeInfo->Name.Length / 2,
+-                objectTypeInfo->Name.Buffer,
+-                objectName.Length / 2,
+-                objectName.Buffer
+-                );
+-            */
+-        }
+-        else
+-        {
+-            /* Print something else. */
+-            /*
+-            printf(
+-                "[%#x] %.*S: (unnamed)\n",
+-                handle.Handle,
+-                objectTypeInfo->Name.Length / 2,
+-                objectTypeInfo->Name.Buffer
+-                );
+-            */
+-            ;;
+-        }
+-        free(objectTypeInfo);
+-        free(objectNameInfo);
+-        CloseHandle(dupHandle);
+-    }
+-    free(handleInfo);
+-    CloseHandle(processHandle);
+-    return filesList;
+-
+-error_py_fun:
+-    Py_XDECREF(arg);
+-    Py_XDECREF(fileFromWchar);
+-    Py_DECREF(filesList);
+-    return NULL;
+-}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_handles.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_handles.h	1969-12-31 16:00:00.000000000 -0800
+@@ -1,12 +0,0 @@
+-/*
+- * $Id: process_info.h 1060 2011-07-02 18:05:26Z g.rodola $
+- *
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- */
+-
+-#include <Python.h>
+-#include <windows.h>
+-
+-PyObject* psutil_get_open_files(long pid, HANDLE processHandle);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_info.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_info.c	1969-12-31 16:00:00.000000000 -0800
+@@ -1,504 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Helper functions related to fetching process information. Used by
+- * _psutil_mswindows module methods.
+- */
+-
+-#include <Python.h>
+-#include <windows.h>
+-#include <Psapi.h>
+-#include <tlhelp32.h>
+-
+-#include "security.h"
+-#include "process_info.h"
+-#include "ntextapi.h"
+-
+-
+-
+-/*
+- * A wrapper around OpenProcess setting NSP exception if process
+- * no longer exists.
+- * "pid" is the process pid, "dwDesiredAccess" is the first argument
+- * exptected by OpenProcess.
+- * Return a process handle or NULL.
+- */
+-HANDLE
+-psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
+-{
+-    HANDLE hProcess;
+-    DWORD  processExitCode = 0;
+-
+-    if (pid == 0) {
+-        // otherwise we'd get NoSuchProcess
+-        return AccessDenied();
+-    }
+-
+-    hProcess = OpenProcess(dwDesiredAccess, FALSE, pid);
+-    if (hProcess == NULL) {
+-        if (GetLastError() == ERROR_INVALID_PARAMETER) {
+-            NoSuchProcess();
+-        }
+-        else {
+-            PyErr_SetFromWindowsErr(0);
+-        }
+-        return NULL;
+-    }
+-
+-    /* make sure the process is running */
+-    GetExitCodeProcess(hProcess, &processExitCode);
+-    if (processExitCode == 0) {
+-        NoSuchProcess();
+-        CloseHandle(hProcess);
+-        return NULL;
+-    }
+-    return hProcess;
+-}
+-
+-
+-/*
+- * Same as psutil_handle_from_pid_waccess but implicitly uses
+- * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
+- * parameter for OpenProcess.
+- */
+-HANDLE
+-psutil_handle_from_pid(DWORD pid) {
+-    DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
+-    return psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
+-}
+-
+-
+-// fetch the PEB base address from NtQueryInformationProcess()
+-PVOID
+-psutil_get_peb_address(HANDLE ProcessHandle)
+-{
+-    _NtQueryInformationProcess NtQueryInformationProcess =
+-        (_NtQueryInformationProcess)GetProcAddress(
+-        GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
+-    PROCESS_BASIC_INFORMATION pbi;
+-
+-    NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
+-    return pbi.PebBaseAddress;
+-}
+-
+-
+-DWORD*
+-psutil_get_pids(DWORD *numberOfReturnedPIDs) {
+-    /* Win32 SDK says the only way to know if our process array
+-     * wasn't large enough is to check the returned size and make
+-     * sure that it doesn't match the size of the array.
+-     * If it does we allocate a larger array and try again */
+-
+-    // Stores the actual array
+-    DWORD *procArray = NULL;
+-    DWORD procArrayByteSz;
+-    int procArraySz = 0;
+-
+-    // Stores the byte size of the returned array from enumprocesses
+-    DWORD enumReturnSz = 0;
+-
+-    do {
+-        procArraySz += 1024;
+-        free(procArray);
+-        procArrayByteSz = procArraySz * sizeof(DWORD);
+-        procArray = malloc(procArrayByteSz);
+-        if (procArray == NULL) {
+-            PyErr_NoMemory();
+-            return NULL;
+-        }
+-        if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) {
+-            free(procArray);
+-            PyErr_SetFromWindowsErr(0);
+-            return NULL;
+-        }
+-    } while(enumReturnSz == procArraySz * sizeof(DWORD));
+-
+-    // The number of elements is the returned size / size of each element
+-    *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD);
+-
+-    return procArray;
+-}
+-
+-
+-int
+-psutil_pid_is_running(DWORD pid)
+-{
+-    HANDLE hProcess;
+-    DWORD exitCode;
+-
+-    // Special case for PID 0 System Idle Process
+-    if (pid == 0) {
+-        return 1;
+-    }
+-
+-    if (pid < 0) {
+-        return 0;
+-    }
+-
+-    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+-                           FALSE, pid);
+-    if (NULL == hProcess) {
+-        // invalid parameter is no such process
+-        if (GetLastError() == ERROR_INVALID_PARAMETER) {
+-            CloseHandle(hProcess);
+-            return 0;
+-        }
+-
+-        // access denied obviously means there's a process to deny access to...
+-        if (GetLastError() == ERROR_ACCESS_DENIED) {
+-            CloseHandle(hProcess);
+-            return 1;
+-        }
+-
+-        CloseHandle(hProcess);
+-        PyErr_SetFromWindowsErr(0);
+-        return -1;
+-    }
+-
+-    if (GetExitCodeProcess(hProcess, &exitCode)) {
+-        CloseHandle(hProcess);
+-        return (exitCode == STILL_ACTIVE);
+-    }
+-
+-    // access denied means there's a process there so we'll assume it's running
+-    if (GetLastError() == ERROR_ACCESS_DENIED) {
+-        CloseHandle(hProcess);
+-        return 1;
+-    }
+-
+-    PyErr_SetFromWindowsErr(0);
+-    CloseHandle(hProcess);
+-    return -1;
+-}
+-
+-
+-int
+-psutil_pid_in_proclist(DWORD pid)
+-{
+-    DWORD *proclist = NULL;
+-    DWORD numberOfReturnedPIDs;
+-    DWORD i;
+-
+-    proclist = psutil_get_pids(&numberOfReturnedPIDs);
+-    if (NULL == proclist) {
+-        return -1;
+-    }
+-
+-    for (i = 0; i < numberOfReturnedPIDs; i++) {
+-        if (pid == proclist[i]) {
+-            free(proclist);
+-            return 1;
+-        }
+-    }
+-
+-    free(proclist);
+-    return 0;
+-}
+-
+-
+-// Check exit code from a process handle. Return FALSE on an error also
+-// XXX - not used anymore
+-int
+-handlep_is_running(HANDLE hProcess)
+-{
+-    DWORD dwCode;
+-    if (NULL == hProcess) {
+-        return 0;
+-    }
+-    if (GetExitCodeProcess(hProcess, &dwCode)) {
+-        if (dwCode == STILL_ACTIVE) {
+-            return 1;
+-        }
+-    }
+-    return 0;
+-}
+-
+-
+-// Return None to represent NoSuchProcess, else return NULL for
+-// other exception or the name as a Python string
+-PyObject*
+-psutil_get_name(long pid)
+-{
+-    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+-    PROCESSENTRY32 pe = { 0 };
+-    pe.dwSize = sizeof(PROCESSENTRY32);
+-
+-    if( Process32First(h, &pe)) {
+-        do {
+-            if (pe.th32ProcessID == pid) {
+-                CloseHandle(h);
+-                return Py_BuildValue("s", pe.szExeFile);
+-            }
+-        } while(Process32Next(h, &pe));
+-
+-        // the process was never found, set NoSuchProcess exception
+-        NoSuchProcess();
+-        CloseHandle(h);
+-        return NULL;
+-    }
+-
+-    CloseHandle(h);
+-    return PyErr_SetFromWindowsErr(0);
+-}
+-
+-
+-/* returns parent pid (as a Python int) for given pid or None on failure */
+-PyObject*
+-psutil_get_ppid(long pid)
+-{
+-    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+-    PROCESSENTRY32 pe = { 0 };
+-    pe.dwSize = sizeof(PROCESSENTRY32);
+-
+-    if( Process32First(h, &pe)) {
+-        do {
+-            if (pe.th32ProcessID == pid) {
+-                CloseHandle(h);
+-                return Py_BuildValue("I", pe.th32ParentProcessID);
+-            }
+-        } while(Process32Next(h, &pe));
+-
+-        // the process was never found, set NoSuchProcess exception
+-        NoSuchProcess();
+-        CloseHandle(h);
+-        return NULL;
+-    }
+-
+-    CloseHandle(h);
+-    return PyErr_SetFromWindowsErr(0);
+-}
+-
+-
+-/*
+- * returns a Python list representing the arguments for the process
+- * with given pid or NULL on error.
+- */
+-PyObject*
+-psutil_get_arg_list(long pid)
+-{
+-    int nArgs, i;
+-    LPWSTR *szArglist = NULL;
+-    HANDLE hProcess = NULL;
+-    PVOID pebAddress;
+-    PVOID rtlUserProcParamsAddress;
+-    UNICODE_STRING commandLine;
+-    WCHAR *commandLineContents = NULL;
+-    PyObject *arg = NULL;
+-    PyObject *arg_from_wchar = NULL;
+-    PyObject *argList = NULL;
+-
+-    hProcess = psutil_handle_from_pid(pid);
+-    if(hProcess == NULL) {
+-        return NULL;
+-    }
+-
+-    pebAddress = psutil_get_peb_address(hProcess);
+-
+-    /* get the address of ProcessParameters */
+-#ifdef _WIN64
+-    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
+-        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
+-#else
+-    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
+-        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
+-#endif
+-    {
+-        ////printf("Could not read the address of ProcessParameters!\n");
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    /* read the CommandLine UNICODE_STRING structure */
+-#ifdef _WIN64
+-    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
+-        &commandLine, sizeof(commandLine), NULL))
+-#else
+-    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
+-        &commandLine, sizeof(commandLine), NULL))
+-#endif
+-    {
+-        ////printf("Could not read CommandLine!\n");
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-
+-    /* allocate memory to hold the command line */
+-    commandLineContents = (WCHAR *)malloc(commandLine.Length+1);
+-    if (commandLineContents == NULL) {
+-        PyErr_NoMemory();
+-        goto error;
+-    }
+-
+-    /* read the command line */
+-    if (!ReadProcessMemory(hProcess, commandLine.Buffer,
+-        commandLineContents, commandLine.Length, NULL))
+-    {
+-        ////printf("Could not read the command line string!\n");
+-        PyErr_SetFromWindowsErr(0);
+-        goto error;
+-    }
+-
+-    /* print the commandline */
+-    ////printf("%.*S\n", commandLine.Length / 2, commandLineContents);
+-
+-    // null-terminate the string to prevent wcslen from returning incorrect length
+-    // the length specifier is in characters, but commandLine.Length is in bytes
+-    commandLineContents[(commandLine.Length/sizeof(WCHAR))] = '\0';
+-
+-    // attemempt tp parse the command line using Win32 API, fall back on string
+-    // cmdline version otherwise
+-    szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
+-    if (NULL == szArglist) {
+-        // failed to parse arglist
+-        // encode as a UTF8 Python string object from WCHAR string
+-        arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
+-                                                commandLine.Length / 2);
+-        if (arg_from_wchar == NULL)
+-            goto error;
+-        #if PY_MAJOR_VERSION >= 3
+-            argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
+-        #else
+-            argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
+-        #endif
+-        if (!argList)
+-            goto error;
+-    }
+-    else {
+-        // arglist parsed as array of UNICODE_STRING, so convert each to Python
+-        // string object and add to arg list
+-        argList = Py_BuildValue("[]");
+-        if (argList == NULL)
+-            goto error;
+-        for(i=0; i<nArgs; i++) {
+-            arg_from_wchar = NULL;
+-            arg = NULL;
+-            ////printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]),
+-            //                  szArglist[i], wcslen(szArglist[i]));
+-            arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
+-                                                    wcslen(szArglist[i])
+-                                                    );
+-            if (arg_from_wchar == NULL)
+-                goto error;
+-            #if PY_MAJOR_VERSION >= 3
+-                arg = PyUnicode_FromObject(arg_from_wchar);
+-            #else
+-                arg = PyUnicode_AsUTF8String(arg_from_wchar);
+-            #endif
+-            if (arg == NULL)
+-                goto error;
+-            Py_XDECREF(arg_from_wchar);
+-            if (PyList_Append(argList, arg))
+-                goto error;
+-            Py_XDECREF(arg);
+-        }
+-    }
+-
+-    if (szArglist != NULL)
+-        LocalFree(szArglist);
+-    free(commandLineContents);
+-    CloseHandle(hProcess);
+-    return argList;
+-
+-error:
+-    Py_XDECREF(arg);
+-    Py_XDECREF(arg_from_wchar);
+-    Py_XDECREF(argList);
+-    if (hProcess != NULL)
+-        CloseHandle(hProcess);
+-    if (commandLineContents != NULL)
+-        free(commandLineContents);
+-    if (szArglist != NULL)
+-        LocalFree(szArglist);
+-    return NULL;
+-}
+-
+-
+-#define PH_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
+-
+-#define PH_NEXT_PROCESS(Process) ( \
+-    ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
+-    (PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
+-    ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
+-    NULL \
+-    )
+-
+-const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
+-const STATUS_BUFFER_TOO_SMALL = 0xC0000023L;
+-
+-/*
+- * Given a process PID and a PSYSTEM_PROCESS_INFORMATION structure
+- * fills the structure with process information.
+- * On success return 1, else 0 with Python exception already set.
+- */
+-int
+-get_process_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess, PVOID *retBuffer)
+-{
+-    static ULONG initialBufferSize = 0x4000;
+-    NTSTATUS status;
+-    PVOID buffer;
+-    ULONG bufferSize;
+-    PSYSTEM_PROCESS_INFORMATION process;
+-
+-    // get NtQuerySystemInformation
+-    typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
+-    NTQSI_PROC NtQuerySystemInformation;
+-    HINSTANCE hNtDll;
+-    hNtDll = LoadLibrary(TEXT("ntdll.dll"));
+-    NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
+-                                hNtDll, "NtQuerySystemInformation");
+-
+-    bufferSize = initialBufferSize;
+-    buffer = malloc(bufferSize);
+-    if (buffer == NULL) {
+-        PyErr_NoMemory();
+-        goto error;
+-    }
+-
+-    while (TRUE) {
+-        status = NtQuerySystemInformation(SystemProcessInformation, buffer,
+-                                          bufferSize, &bufferSize);
+-
+-        if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
+-        {
+-            free(buffer);
+-            buffer = malloc(bufferSize);
+-            if (buffer == NULL) {
+-                PyErr_NoMemory();
+-                goto error;
+-            }
+-        }
+-        else {
+-            break;
+-        }
+-    }
+-
+-    if (status != 0) {
+-        PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
+-        goto error;
+-    }
+-
+-    if (bufferSize <= 0x20000) {
+-        initialBufferSize = bufferSize;
+-    }
+-
+-    process = PH_FIRST_PROCESS(buffer);
+-    do {
+-        if (process->UniqueProcessId == (HANDLE)pid) {
+-            *retProcess = process;
+-            *retBuffer = buffer;
+-            return 1;
+-        }
+-    } while ( (process = PH_NEXT_PROCESS(process)) );
+-
+-    NoSuchProcess();
+-    goto error;
+-
+-error:
+-    FreeLibrary(hNtDll);
+-    if (buffer != NULL)
+-        free(buffer);
+-    return 0;
+-}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_info.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/process_info.h	1969-12-31 16:00:00.000000000 -0800
+@@ -1,23 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Helper functions related to fetching process information. Used by _psutil_mswindows
+- * module methods.
+- */
+-
+-#include <Python.h>
+-#include <windows.h>
+-
+-HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
+-HANDLE psutil_handle_from_pid(DWORD pid);
+-PVOID psutil_get_peb_address(HANDLE ProcessHandle);
+-HANDLE psutil_handle_from_pid(DWORD pid);
+-int psutil_pid_in_proclist(DWORD pid);
+-int psutil_pid_is_running(DWORD pid);
+-int psutil_handlep_is_running(HANDLE hProcess);
+-PyObject* psutil_get_arg_list(long pid);
+-PyObject* psutil_get_ppid(long pid);
+-PyObject* psutil_get_name(long pid);
+-DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/security.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/security.c	1969-12-31 16:00:00.000000000 -0800
+@@ -1,235 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Security related functions for Windows platform (Set privileges such as
+- * SeDebug), as well as security helper functions.
+- */
+-
+-#include <windows.h>
+-#include <Python.h>
+-
+-/*
+- * Convert a process handle to a process token handle.
+- */
+-HANDLE
+-token_from_handle(HANDLE hProcess) {
+-    HANDLE hToken = NULL;
+-
+-    if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) ) {
+-        return PyErr_SetFromWindowsErr(0);
+-    }
+-
+-    return hToken;
+-}
+-
+-
+-/*
+- * http://www.ddj.com/windows/184405986
+- *
+- * There's a way to determine whether we're running under the Local System
+- * account. However (you guessed it), we have to call more Win32 functions to
+- * determine this. Backing up through the code listing, we need to make another
+- * call to GetTokenInformation, but instead of passing through the TOKEN_USER
+- * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns
+- * an array of privileges that the account has in the environment. Iterating
+- * through the array, we call the function LookupPrivilegeName looking for the
+- * string �SeTcbPrivilege. If the function returns this string, then this
+- * account has Local System privileges
+- */
+-int HasSystemPrivilege(HANDLE hProcess) {
+-    DWORD i;
+-    DWORD dwSize = 0;
+-    DWORD dwRetval = 0;
+-    TCHAR privName[256];
+-    DWORD dwNameSize = 256;
+-    //PTOKEN_PRIVILEGES tp = NULL;
+-    BYTE *pBuffer = NULL;
+-    TOKEN_PRIVILEGES* tp = NULL;
+-    HANDLE hToken = token_from_handle(hProcess);
+-
+-    if (NULL == hToken) {
+-        return -1;
+-    }
+-
+-    // call GetTokenInformation first to get the buffer size
+-    if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) {
+-        dwRetval = GetLastError();
+-        // if it failed for a reason other than the buffer, bail out
+-        if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) {
+-            PyErr_SetFromWindowsErr(dwRetval);
+-            return 0;
+-        }
+-    }
+-
+-    // allocate buffer and call GetTokenInformation again
+-    //tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
+-    pBuffer = (BYTE *) malloc(dwSize);
+-    if (pBuffer == NULL) {
+-        PyErr_NoMemory();
+-        return -1;
+-    }
+-
+-    if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwSize, &dwSize) ) {
+-        PyErr_SetFromWindowsErr(0);
+-        free(pBuffer);
+-        return -1;
+-    }
+-
+-    // convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer
+-    tp = (TOKEN_PRIVILEGES*)pBuffer;
+-
+-    // check all the privileges looking for SeTcbPrivilege
+-    for(i=0; i < tp->PrivilegeCount; i++) {
+-        // reset the buffer contents and the buffer size
+-        strcpy(privName, "");
+-        dwNameSize = sizeof(privName) / sizeof(TCHAR);
+-        if (! LookupPrivilegeName(NULL,
+-                &tp->Privileges[i].Luid,
+-                (LPTSTR)privName,
+-                &dwNameSize)) {
+-
+-            PyErr_SetFromWindowsErr(0);
+-            free(pBuffer);
+-            return -1;
+-        }
+-
+-        // if we find the SeTcbPrivilege then it's a LocalSystem process
+-        if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) {
+-            free(pBuffer);
+-            return 1;
+-        }
+-
+-    } //for
+-
+-    free(pBuffer);
+-    return 0;
+-}
+-
+-
+-BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
+-{
+-    TOKEN_PRIVILEGES tp;
+-    LUID luid;
+-    TOKEN_PRIVILEGES tpPrevious;
+-    DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
+-
+-    if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
+-
+-    // first pass.  get current privilege setting
+-    tp.PrivilegeCount = 1;
+-    tp.Privileges[0].Luid = luid;
+-    tp.Privileges[0].Attributes = 0;
+-
+-    AdjustTokenPrivileges(
+-        hToken,
+-        FALSE,
+-        &tp,
+-        sizeof(TOKEN_PRIVILEGES),
+-        &tpPrevious,
+-        &cbPrevious
+-    );
+-
+-    if (GetLastError() != ERROR_SUCCESS) return FALSE;
+-
+-    // second pass. set privilege based on previous setting
+-    tpPrevious.PrivilegeCount = 1;
+-    tpPrevious.Privileges[0].Luid = luid;
+-
+-    if(bEnablePrivilege) {
+-        tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
+-    }
+-
+-    else {
+-        tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
+-                tpPrevious.Privileges[0].Attributes);
+-    }
+-
+-    AdjustTokenPrivileges(
+-        hToken,
+-        FALSE,
+-        &tpPrevious,
+-        cbPrevious,
+-        NULL,
+-        NULL
+-    );
+-
+-    if (GetLastError() != ERROR_SUCCESS) return FALSE;
+-
+-    return TRUE;
+-}
+-
+-
+-int SetSeDebug()
+-{
+-    HANDLE hToken;
+-    if(! OpenThreadToken(GetCurrentThread(),
+-                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+-                         FALSE,
+-                         &hToken)
+-                         ){
+-        if (GetLastError() == ERROR_NO_TOKEN){
+-            if (!ImpersonateSelf(SecurityImpersonation)){
+-                CloseHandle(hToken);
+-                return 0;
+-            }
+-            if (!OpenThreadToken(GetCurrentThread(),
+-                                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+-                                 FALSE,
+-                                 &hToken)
+-                                 ){
+-                RevertToSelf();
+-                CloseHandle(hToken);
+-                return 0;
+-            }
+-        }
+-    }
+-
+-    // enable SeDebugPrivilege (open any process)
+-    if (! SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)){
+-        RevertToSelf();
+-        CloseHandle(hToken);
+-        return 0;
+-    }
+-
+-    RevertToSelf();
+-    CloseHandle(hToken);
+-    return 1;
+-}
+-
+-
+-int UnsetSeDebug()
+-{
+-    HANDLE hToken;
+-    if(! OpenThreadToken(GetCurrentThread(),
+-                        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+-                        FALSE,
+-                        &hToken)
+-                        ){
+-        if(GetLastError() == ERROR_NO_TOKEN){
+-            if(! ImpersonateSelf(SecurityImpersonation)){
+-                //Log2File("Error setting impersonation! [UnsetSeDebug()]", L_DEBUG);
+-                return 0;
+-            }
+-
+-            if(!OpenThreadToken(GetCurrentThread(),
+-                                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+-                                FALSE,
+-                                &hToken)
+-                                ){
+-                //Log2File("Error Opening Thread Token! [UnsetSeDebug()]", L_DEBUG);
+-                return 0;
+-            }
+-        }
+-    }
+-
+-    //now disable SeDebug
+-    if(!SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)){
+-        //Log2File("Error unsetting SeDebug Privilege [SetPrivilege()]", L_WARN);
+-        return 0;
+-    }
+-
+-    CloseHandle(hToken);
+-    return 1;
+-}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/security.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/mswindows/security.h	1969-12-31 16:00:00.000000000 -0800
+@@ -1,18 +0,0 @@
+-/*
+- * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+- * Use of this source code is governed by a BSD-style license that can be
+- * found in the LICENSE file.
+- *
+- * Security related functions for Windows platform (Set privileges such as
+- * SeDebug), as well as security helper functions.
+- */
+-
+-#include <windows.h>
+-
+-
+-BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege);
+-int SetSeDebug();
+-int UnsetSeDebug();
+-HANDLE token_from_handle(HANDLE hProcess);
+-int HasSystemPrivilege(HANDLE hProcess);
+-
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/osx/process_info.c	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/osx/process_info.c	2015-06-17 19:33:33.000000000 -0700
+@@ -3,14 +3,15 @@
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+  *
+- * Helper functions related to fetching process information. Used by _psutil_osx
+- * module methods.
++ * Helper functions related to fetching process information.
++ * Used by _psutil_osx module methods.
+  */
+ 
++
+ #include <Python.h>
+ #include <assert.h>
+ #include <errno.h>
+-#include <limits.h>  /* for INT_MAX */
++#include <limits.h>  // for INT_MAX
+ #include <stdbool.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+@@ -31,22 +32,18 @@
+     int kill_ret;
+ 
+     // save some time if it's an invalid PID
+-    if (pid < 0) {
++    if (pid < 0)
+         return 0;
+-    }
+-
+     // if kill returns success of permission denied we know it's a valid PID
+     kill_ret = kill(pid , 0);
+-    if ( (0 == kill_ret) || (EPERM == errno) ) {
++    if ( (0 == kill_ret) || (EPERM == errno))
+         return 1;
+-    }
+ 
+     // otherwise return 0 for PID not found
+     return 0;
+ }
+ 
+ 
+-
+ /*
+  * Returns a list of all BSD processes on the system.  This routine
+  * allocates the list and puts it in *procList and a count of the
+@@ -58,12 +55,12 @@
+ int
+ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount)
+ {
+-    /* Declaring mib as const requires use of a cast since the
+-     * sysctl prototype doesn't include the const modifier. */
++    // Declaring mib as const requires use of a cast since the
++    // sysctl prototype doesn't include the const modifier.
+     static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+     size_t           size, size2;
+     void            *ptr;
+-    int              err, lim = 8;  /* some limit */
++    int              err, lim = 8;  // some limit
+ 
+     assert( procList != NULL);
+     assert(*procList == NULL);
+@@ -71,7 +68,8 @@
+ 
+     *procCount = 0;
+ 
+-    /* We start by calling sysctl with ptr == NULL and size == 0.
++    /*
++     * We start by calling sysctl with ptr == NULL and size == 0.
+      * That will succeed, and set size to the appropriate length.
+      * We then allocate a buffer of at least that size and call
+      * sysctl with that buffer.  If that succeeds, we're done.
+@@ -84,34 +82,29 @@
+      */
+     while (lim-- > 0) {
+         size = 0;
+-        if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1) {
++        if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1)
+             return errno;
+-        }
+-
+-        size2 = size + (size >> 3);  /* add some */
++        size2 = size + (size >> 3);  // add some
+         if (size2 > size) {
+             ptr = malloc(size2);
+-            if (ptr == NULL) {
++            if (ptr == NULL)
+                 ptr = malloc(size);
+-            } else {
++            else
+                 size = size2;
+-            }
+         }
+         else {
+             ptr = malloc(size);
+         }
+-        if (ptr == NULL) {
++        if (ptr == NULL)
+             return ENOMEM;
+-        }
+ 
+         if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) {
+             err = errno;
+             free(ptr);
+-            if (err != ENOMEM) {
++            if (err != ENOMEM)
+                 return err;
+-            }
+-
+-        } else {
++        }
++        else {
+             *procList = (kinfo_proc *)ptr;
+             *procCount = size / sizeof(kinfo_proc);
+             return 0;
+@@ -121,7 +114,7 @@
+ }
+ 
+ 
+-/* Read the maximum argument size for processes */
++// Read the maximum argument size for processes
+ int
+ psutil_get_argmax()
+ {
+@@ -129,15 +122,14 @@
+     int mib[] = { CTL_KERN, KERN_ARGMAX };
+     size_t size = sizeof(argmax);
+ 
+-    if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0) {
++    if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0)
+         return argmax;
+-    }
+     return 0;
+ }
+ 
+ 
+-/* return process args as a python list */
+-PyObject*
++// return process args as a python list
++PyObject *
+ psutil_get_arg_list(long pid)
+ {
+     int mib[3];
+@@ -151,12 +143,11 @@
+     PyObject *arg = NULL;
+     PyObject *arglist = NULL;
+ 
+-    //special case for PID 0 (kernel_task) where cmdline cannot be fetched
+-    if (pid == 0) {
++    // special case for PID 0 (kernel_task) where cmdline cannot be fetched
++    if (pid == 0)
+         return Py_BuildValue("[]");
+-    }
+ 
+-    /* read argmax and allocate memory for argument space. */
++    // read argmax and allocate memory for argument space.
+     argmax = psutil_get_argmax();
+     if (! argmax) {
+         PyErr_SetFromErrno(PyExc_OSError);
+@@ -169,23 +160,23 @@
+         goto error;
+     }
+ 
+-    /* read argument space */
++    // read argument space
+     mib[0] = CTL_KERN;
+     mib[1] = KERN_PROCARGS2;
+     mib[2] = pid;
+     if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
+-        if (EINVAL == errno) { // invalid == access denied OR nonexistent PID
+-            if ( psutil_pid_exists(pid) ) {
++        if (EINVAL == errno) {
++            // EINVAL == access denied OR nonexistent PID
++            if (psutil_pid_exists(pid))
+                 AccessDenied();
+-            } else {
++            else
+                 NoSuchProcess();
+-            }
+         }
+         goto error;
+     }
+ 
+     arg_end = &procargs[argmax];
+-    /* copy the number of arguments to nargs */
++    // copy the number of arguments to nargs
+     memcpy(&nargs, procargs, sizeof(nargs));
+ 
+     arg_ptr = procargs + sizeof(nargs);
+@@ -199,12 +190,11 @@
+ 
+     // skip ahead to the first argument
+     for (; arg_ptr < arg_end; arg_ptr++) {
+-        if (*arg_ptr != '\0') {
++        if (*arg_ptr != '\0')
+             break;
+-        }
+     }
+ 
+-    /* iterate through arguments */
++    // iterate through arguments
+     curr_arg = arg_ptr;
+     arglist = Py_BuildValue("[]");
+     if (!arglist)
+@@ -255,9 +245,7 @@
+         return -1;
+     }
+ 
+-    /*
+-     * sysctl succeeds but len is zero, happens when process has gone away
+-     */
++    // sysctl succeeds but len is zero, happens when process has gone away
+     if (len == 0) {
+         NoSuchProcess();
+         return -1;
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/osx/process_info.h	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/osx/process_info.h	2015-06-17 19:33:33.000000000 -0700
+@@ -2,19 +2,15 @@
+  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+  * Use of this source code is governed by a BSD-style license that can be
+  * found in the LICENSE file.
+- *
+- * Helper functions related to fetching process information. Used by _psutil_osx
+- * module methods.
+  */
+ 
+ #include <Python.h>
+ 
+-
+ typedef struct kinfo_proc kinfo_proc;
+ 
+-int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
+-int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
+ int psutil_get_argmax(void);
++int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
++int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
+ int psutil_pid_exists(long pid);
+ int psutil_proc_pidinfo(long pid, int flavor, void *pti, int size);
+ PyObject* psutil_get_arg_list(long pid);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/glpi.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/glpi.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,41 @@
++// mingw headers are missing this
++
++typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
++    RelationProcessorCore,
++    RelationNumaNode,
++    RelationCache,
++    RelationProcessorPackage,
++    RelationGroup,
++    RelationAll=0xffff
++} LOGICAL_PROCESSOR_RELATIONSHIP;
++
++typedef enum _PROCESSOR_CACHE_TYPE {
++    CacheUnified,CacheInstruction,CacheData,CacheTrace
++} PROCESSOR_CACHE_TYPE;
++
++typedef struct _CACHE_DESCRIPTOR {
++    BYTE Level;
++    BYTE Associativity;
++    WORD LineSize;
++    DWORD Size;
++    PROCESSOR_CACHE_TYPE Type;
++} CACHE_DESCRIPTOR,*PCACHE_DESCRIPTOR;
++
++typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
++    ULONG_PTR ProcessorMask;
++    LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
++    union {
++        struct {
++            BYTE Flags;
++        } ProcessorCore;
++        struct {
++            DWORD NodeNumber;
++        } NumaNode;
++        CACHE_DESCRIPTOR Cache;
++        ULONGLONG Reserved[2];
++    };
++} SYSTEM_LOGICAL_PROCESSOR_INFORMATION,*PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
++
++WINBASEAPI WINBOOL WINAPI
++GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
++                               PDWORD ReturnedLength);
+\ No newline at end of file
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/ntextapi.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/ntextapi.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,292 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#if !defined(__NTEXTAPI_H__)
++#define __NTEXTAPI_H__
++
++typedef enum _KTHREAD_STATE {
++    Initialized,
++    Ready,
++    Running,
++    Standby,
++    Terminated,
++    Waiting,
++    Transition,
++    DeferredReady,
++    GateWait,
++    MaximumThreadState
++} KTHREAD_STATE, *PKTHREAD_STATE;
++
++typedef enum _KWAIT_REASON {
++    Executive = 0,
++    FreePage = 1,
++    PageIn = 2,
++    PoolAllocation = 3,
++    DelayExecution = 4,
++    Suspended = 5,
++    UserRequest = 6,
++    WrExecutive = 7,
++    WrFreePage = 8,
++    WrPageIn = 9,
++    WrPoolAllocation = 10,
++    WrDelayExecution = 11,
++    WrSuspended = 12,
++    WrUserRequest = 13,
++    WrEventPair = 14,
++    WrQueue = 15,
++    WrLpcReceive = 16,
++    WrLpcReply = 17,
++    WrVirtualMemory = 18,
++    WrPageOut = 19,
++    WrRendezvous = 20,
++    Spare2 = 21,
++    Spare3 = 22,
++    Spare4 = 23,
++    Spare5 = 24,
++    WrCalloutStack = 25,
++    WrKernel = 26,
++    WrResource = 27,
++    WrPushLock = 28,
++    WrMutex = 29,
++    WrQuantumEnd = 30,
++    WrDispatchInt = 31,
++    WrPreempted = 32,
++    WrYieldExecution = 33,
++    WrFastMutex = 34,
++    WrGuardedMutex = 35,
++    WrRundown = 36,
++    MaximumWaitReason = 37
++} KWAIT_REASON, *PKWAIT_REASON;
++
++typedef struct _CLIENT_ID {
++    HANDLE UniqueProcess;
++    HANDLE UniqueThread;
++} CLIENT_ID, *PCLIENT_ID;
++
++
++typedef struct _UNICODE_STRING {
++    USHORT Length;
++    USHORT MaximumLength;
++    PWSTR Buffer;
++} UNICODE_STRING, *PUNICODE_STRING;
++
++typedef struct _SYSTEM_TIMEOFDAY_INFORMATION {
++    LARGE_INTEGER BootTime;
++    LARGE_INTEGER CurrentTime;
++    LARGE_INTEGER TimeZoneBias;
++    ULONG TimeZoneId;
++    ULONG Reserved;
++    ULONGLONG BootTimeBias;
++    ULONGLONG SleepTimeBias;
++} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
++
++typedef struct _SYSTEM_THREAD_INFORMATION {
++    LARGE_INTEGER KernelTime;
++    LARGE_INTEGER UserTime;
++    LARGE_INTEGER CreateTime;
++    ULONG WaitTime;
++    PVOID StartAddress;
++    CLIENT_ID ClientId;
++    LONG Priority;
++    LONG BasePriority;
++    ULONG ContextSwitches;
++    ULONG ThreadState;
++    KWAIT_REASON WaitReason;
++} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
++
++typedef struct _TEB *PTEB;
++
++// private
++typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION {
++    SYSTEM_THREAD_INFORMATION ThreadInfo;
++    PVOID StackBase;
++    PVOID StackLimit;
++    PVOID Win32StartAddress;
++    PTEB TebBase;
++    ULONG_PTR Reserved2;
++    ULONG_PTR Reserved3;
++    ULONG_PTR Reserved4;
++} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
++
++typedef struct _SYSTEM_PROCESS_INFORMATION {
++    ULONG NextEntryOffset;
++    ULONG NumberOfThreads;
++    LARGE_INTEGER SpareLi1;
++    LARGE_INTEGER SpareLi2;
++    LARGE_INTEGER SpareLi3;
++    LARGE_INTEGER CreateTime;
++    LARGE_INTEGER UserTime;
++    LARGE_INTEGER KernelTime;
++    UNICODE_STRING ImageName;
++    LONG BasePriority;
++    HANDLE UniqueProcessId;
++    HANDLE InheritedFromUniqueProcessId;
++    ULONG HandleCount;
++    ULONG SessionId;
++    ULONG_PTR PageDirectoryBase;
++    SIZE_T PeakVirtualSize;
++    SIZE_T VirtualSize;
++    DWORD PageFaultCount;
++    SIZE_T PeakWorkingSetSize;
++    SIZE_T WorkingSetSize;
++    SIZE_T QuotaPeakPagedPoolUsage;
++    SIZE_T QuotaPagedPoolUsage;
++    SIZE_T QuotaPeakNonPagedPoolUsage;
++    SIZE_T QuotaNonPagedPoolUsage;
++    SIZE_T PagefileUsage;
++    SIZE_T PeakPagefileUsage;
++    SIZE_T PrivatePageCount;
++    LARGE_INTEGER ReadOperationCount;
++    LARGE_INTEGER WriteOperationCount;
++    LARGE_INTEGER OtherOperationCount;
++    LARGE_INTEGER ReadTransferCount;
++    LARGE_INTEGER WriteTransferCount;
++    LARGE_INTEGER OtherTransferCount;
++    SYSTEM_THREAD_INFORMATION Threads[1];
++} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
++
++
++// structures and enums from winternl.h (not available under mingw)
++typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
++    LARGE_INTEGER IdleTime;
++    LARGE_INTEGER KernelTime;
++    LARGE_INTEGER UserTime;
++    LARGE_INTEGER Reserved1[2];
++    ULONG Reserved2;
++} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION,
++    *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
++
++
++typedef enum _SYSTEM_INFORMATION_CLASS {
++    SystemBasicInformation = 0,
++    SystemPerformanceInformation = 2,
++    SystemTimeOfDayInformation = 3,
++    SystemProcessInformation = 5,
++    SystemProcessorPerformanceInformation = 8,
++    SystemInterruptInformation = 23,
++    SystemExceptionInformation = 33,
++    SystemRegistryQuotaInformation = 37,
++    SystemLookasideInformation = 45
++} SYSTEM_INFORMATION_CLASS;
++
++
++// ================================================
++// psutil.users() support
++// ================================================
++
++typedef struct _WINSTATION_INFO {
++    BYTE Reserved1[72];
++    ULONG SessionId;
++    BYTE Reserved2[4];
++    FILETIME ConnectTime;
++    FILETIME DisconnectTime;
++    FILETIME LastInputTime;
++    FILETIME LoginTime;
++    BYTE Reserved3[1096];
++    FILETIME CurrentTime;
++} WINSTATION_INFO, *PWINSTATION_INFO;
++
++typedef enum _WINSTATIONINFOCLASS {
++     WinStationInformation = 8
++} WINSTATIONINFOCLASS;
++
++typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
++                 (HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
++
++typedef struct _WINSTATIONINFORMATIONW {
++    BYTE Reserved2[70];
++    ULONG LogonId;
++    BYTE Reserved3[1140];
++} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
++
++// mingw support:
++// http://www.koders.com/c/fid7C02CAE627C526914CDEB427405B51DF393A5EFA.aspx
++#ifndef _INC_WTSAPI
++typedef struct _WTS_CLIENT_ADDRESS {
++    DWORD AddressFamily;  // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
++    BYTE  Address[20];    // client network address
++} WTS_CLIENT_ADDRESS, * PWTS_CLIENT_ADDRESS;
++
++HANDLE WINAPI WTSOpenServerA(IN LPSTR pServerName);
++
++VOID WINAPI WTSCloseServer(IN HANDLE hServer);
++#endif
++
++
++/*
++ * NtQueryInformationProcess code taken from
++ * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
++ * typedefs needed to compile against ntdll functions not exposted in the API
++ */
++typedef LONG NTSTATUS;
++
++typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
++    HANDLE ProcessHandle,
++    DWORD ProcessInformationClass,
++    PVOID ProcessInformation,
++    DWORD ProcessInformationLength,
++    PDWORD ReturnLength
++);
++
++typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
++    HANDLE ProcessHandle,
++    DWORD ProcessInformationClass,
++    PVOID ProcessInformation,
++    DWORD ProcessInformationLength
++);
++
++typedef struct _PROCESS_BASIC_INFORMATION {
++    PVOID Reserved1;
++    PVOID PebBaseAddress;
++    PVOID Reserved2[2];
++    ULONG_PTR UniqueProcessId;
++    PVOID Reserved3;
++} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
++
++typedef enum _PROCESSINFOCLASS {
++    ProcessBasicInformation,
++    ProcessQuotaLimits,
++    ProcessIoCounters,
++    ProcessVmCounters,
++    ProcessTimes,
++    ProcessBasePriority,
++    ProcessRaisePriority,
++    ProcessDebugPort,
++    ProcessExceptionPort,
++    ProcessAccessToken,
++    ProcessLdtInformation,
++    ProcessLdtSize,
++    ProcessDefaultHardErrorMode,
++    ProcessIoPortHandlers,
++    ProcessPooledUsageAndLimits,
++    ProcessWorkingSetWatch,
++    ProcessUserModeIOPL,
++    ProcessEnableAlignmentFaultFixup,
++    ProcessPriorityClass,
++    ProcessWx86Information,
++    ProcessHandleCount,
++    ProcessAffinityMask,
++    ProcessPriorityBoost,
++    ProcessDeviceMap,
++    ProcessSessionInformation,
++    ProcessForegroundInformation,
++    ProcessWow64Information,
++    /* added after XP+ */
++    ProcessImageFileName,
++    ProcessLUIDDeviceMapsEnabled,
++    ProcessBreakOnTermination,
++    ProcessDebugObjectHandle,
++    ProcessDebugFlags,
++    ProcessHandleTracing,
++    ProcessIoPriority,
++    ProcessExecuteFlags,
++    ProcessResourceManagement,
++    ProcessCookie,
++    ProcessImageInformation,
++    MaxProcessInfoClass
++} PROCESSINFOCLASS;
++
++#endif // __NTEXTAPI_H__
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_handles.c	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_handles.c	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,383 @@
++/*
++ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ */
++
++#ifndef UNICODE
++#define UNICODE
++#endif
++
++#include <Python.h>
++#include <stdio.h>
++#include <windows.h>
++#include <strsafe.h>
++#include "process_handles.h"
++
++#ifndef NT_SUCCESS
++#define NT_SUCCESS(x) ((x) >= 0)
++#endif
++
++#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
++
++#include <winternl.h>
++#define ObjectBasicInformation 0
++#define ObjectNameInformation 1
++#define ObjectTypeInformation 2
++
++#define HANDLE_TYPE_FILE 28
++
++
++typedef LONG NTSTATUS;
++
++typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
++    ULONG SystemInformationClass,
++    PVOID SystemInformation,
++    ULONG SystemInformationLength,
++    PULONG ReturnLength
++);
++
++typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
++    HANDLE SourceProcessHandle,
++    HANDLE SourceHandle,
++    HANDLE TargetProcessHandle,
++    PHANDLE TargetHandle,
++    ACCESS_MASK DesiredAccess,
++    ULONG Attributes,
++    ULONG Options
++);
++
++typedef NTSTATUS (NTAPI *_NtQueryObject)(
++    HANDLE ObjectHandle,
++    ULONG ObjectInformationClass,
++    PVOID ObjectInformation,
++    ULONG ObjectInformationLength,
++    PULONG ReturnLength
++);
++
++
++// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
++const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64;
++
++typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
++{
++    PVOID Object;
++    HANDLE UniqueProcessId;
++    HANDLE HandleValue;
++    ULONG GrantedAccess;
++    USHORT CreatorBackTraceIndex;
++    USHORT ObjectTypeIndex;
++    ULONG HandleAttributes;
++    ULONG Reserved;
++} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
++
++typedef struct _SYSTEM_HANDLE_INFORMATION_EX
++{
++    ULONG_PTR NumberOfHandles;
++    ULONG_PTR Reserved;
++    SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
++} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
++
++
++typedef enum _POOL_TYPE {
++    NonPagedPool,
++    PagedPool,
++    NonPagedPoolMustSucceed,
++    DontUseThisType,
++    NonPagedPoolCacheAligned,
++    PagedPoolCacheAligned,
++    NonPagedPoolCacheAlignedMustS
++} POOL_TYPE, *PPOOL_TYPE;
++
++typedef struct _OBJECT_TYPE_INFORMATION {
++    UNICODE_STRING Name;
++    ULONG TotalNumberOfObjects;
++    ULONG TotalNumberOfHandles;
++    ULONG TotalPagedPoolUsage;
++    ULONG TotalNonPagedPoolUsage;
++    ULONG TotalNamePoolUsage;
++    ULONG TotalHandleTableUsage;
++    ULONG HighWaterNumberOfObjects;
++    ULONG HighWaterNumberOfHandles;
++    ULONG HighWaterPagedPoolUsage;
++    ULONG HighWaterNonPagedPoolUsage;
++    ULONG HighWaterNamePoolUsage;
++    ULONG HighWaterHandleTableUsage;
++    ULONG InvalidAttributes;
++    GENERIC_MAPPING GenericMapping;
++    ULONG ValidAccess;
++    BOOLEAN SecurityRequired;
++    BOOLEAN MaintainHandleCount;
++    USHORT MaintainTypeList;
++    POOL_TYPE PoolType;
++    ULONG PagedPoolUsage;
++    ULONG NonPagedPoolUsage;
++} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
++
++
++PVOID
++GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
++{
++    return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
++}
++
++void PrintError(LPTSTR lpszFunction)
++{
++    // Retrieve the system error message for the last-error code
++
++    LPVOID lpMsgBuf;
++    LPVOID lpDisplayBuf;
++    DWORD dw = GetLastError();
++
++    FormatMessage(
++        FORMAT_MESSAGE_ALLOCATE_BUFFER |
++        FORMAT_MESSAGE_FROM_SYSTEM |
++        FORMAT_MESSAGE_IGNORE_INSERTS,
++        NULL,
++        dw,
++        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
++        (LPTSTR) &lpMsgBuf,
++        0, NULL );
++
++    // Display the error message
++    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
++        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
++    StringCchPrintf((LPTSTR)lpDisplayBuf,
++        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
++        TEXT("%s failed with error %d: %s"),
++        lpszFunction, dw, lpMsgBuf);
++
++    wprintf(lpDisplayBuf);
++    LocalFree(lpMsgBuf);
++    LocalFree(GetLastError);
++}
++
++PyObject *
++psutil_get_open_files(long pid, HANDLE processHandle)
++{
++    _NtQuerySystemInformation NtQuerySystemInformation =
++        GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
++
++    _NtQueryObject NtQueryObject =
++        GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
++
++    NTSTATUS                    status;
++    PSYSTEM_HANDLE_INFORMATION_EX  handleInfo;
++    ULONG                       handleInfoSize = 0x10000;
++    ULONG                       i;
++    ULONG                       fileNameLength;
++    PyObject                    *filesList = Py_BuildValue("[]");
++    PyObject                    *arg = NULL;
++    PyObject                    *fileFromWchar = NULL;
++    DWORD nReturn = 0;
++
++    if (filesList == NULL)
++        return NULL;
++
++    handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(GetProcessHeap(), 0,
++            handleInfoSize);
++
++    if (handleInfo == NULL) {
++        Py_DECREF(filesList);
++        PyErr_NoMemory();
++        return NULL;
++    }
++
++    // NtQuerySystemInformation won't give us the correct buffer size,
++    // so we guess by doubling the buffer size.
++    while ((status = NtQuerySystemInformation(
++                         SystemExtendedHandleInformation,
++                         handleInfo,
++                         handleInfoSize,
++                         &nReturn
++                     )) == STATUS_INFO_LENGTH_MISMATCH)
++    {
++        handleInfoSize *=2;
++        HeapFree(GetProcessHeap(), 0, handleInfo);
++        handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(
++            GetProcessHeap(), 0, handleInfoSize);
++    }
++
++    // NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH
++    if (!NT_SUCCESS(status)) {
++        Py_DECREF(filesList);
++        HeapFree(GetProcessHeap(), 0, handleInfo);
++        return NULL;
++    }
++
++     for (i = 0; i < handleInfo->NumberOfHandles; i++) {
++        PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = &handleInfo->Handles[i];
++        HANDLE                   dupHandle = NULL;
++        HANDLE                   mapHandle = NULL;
++        POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
++        PVOID                    objectNameInfo;
++        UNICODE_STRING           objectName;
++        ULONG                    returnLength;
++        DWORD                    error = 0;
++        fileFromWchar = NULL;
++        arg = NULL;
++
++        // Check if this handle belongs to the PID the user specified.
++        if (handle->UniqueProcessId != (HANDLE)pid ||
++                handle->ObjectTypeIndex != HANDLE_TYPE_FILE)
++        {
++            continue;
++        }
++
++        // Skip handles with the following access codes as the next call
++        // to NtDuplicateObject() or NtQueryObject() might hang forever.
++        if ((handle->GrantedAccess == 0x0012019f)
++                || (handle->GrantedAccess == 0x001a019f)
++                || (handle->GrantedAccess == 0x00120189)
++                || (handle->GrantedAccess == 0x00100000)) {
++            continue;
++        }
++
++       if (!DuplicateHandle(processHandle,
++                             handle->HandleValue,
++                             GetCurrentProcess(),
++                             &dupHandle,
++                             0,
++                             TRUE,
++                             DUPLICATE_SAME_ACCESS))
++         {
++             //printf("[%#x] Error: %d \n", handle->HandleValue, GetLastError());
++             continue;
++         }
++
++        mapHandle = CreateFileMapping(dupHandle,
++                                      NULL,
++                                      PAGE_READONLY,
++                                      0,
++                                      0,
++                                      NULL);
++        if (mapHandle == NULL) {
++            error = GetLastError();
++            if (error == ERROR_INVALID_HANDLE || error == ERROR_BAD_EXE_FORMAT) {
++                CloseHandle(dupHandle);
++                //printf("CreateFileMapping Error: %d\n", error);
++                continue;
++            }
++        }
++        CloseHandle(mapHandle);
++
++        // Query the object type.
++        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
++        if (!NT_SUCCESS(NtQueryObject(
++                            dupHandle,
++                            ObjectTypeInformation,
++                            objectTypeInfo,
++                            0x1000,
++                            NULL
++                        )))
++        {
++            free(objectTypeInfo);
++            CloseHandle(dupHandle);
++            continue;
++        }
++
++        objectNameInfo = malloc(0x1000);
++        if (!NT_SUCCESS(NtQueryObject(
++                            dupHandle,
++                            ObjectNameInformation,
++                            objectNameInfo,
++                            0x1000,
++                            &returnLength
++                        )))
++        {
++            // Reallocate the buffer and try again.
++            objectNameInfo = realloc(objectNameInfo, returnLength);
++            if (!NT_SUCCESS(NtQueryObject(
++                                dupHandle,
++                                ObjectNameInformation,
++                                objectNameInfo,
++                                returnLength,
++                                NULL
++                            )))
++            {
++                // We have the type name, so just display that.
++                /*
++                printf(
++                    "[%#x] %.*S: (could not get name)\n",
++                    handle->HandleValue,
++                    objectTypeInfo->Name.Length / 2,
++                    objectTypeInfo->Name.Buffer
++                    );
++                */
++                free(objectTypeInfo);
++                free(objectNameInfo);
++                CloseHandle(dupHandle);
++                continue;
++
++            }
++        }
++
++        // Cast our buffer into an UNICODE_STRING.
++        objectName = *(PUNICODE_STRING)objectNameInfo;
++
++        // Print the information!
++        if (objectName.Length)
++        {
++            // The object has a name.  Make sure it is a file otherwise
++            // ignore it
++            fileNameLength = objectName.Length / 2;
++            if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
++                // printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
++                fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
++                                                       fileNameLength);
++                if (fileFromWchar == NULL)
++                    goto error_py_fun;
++#if PY_MAJOR_VERSION >= 3
++                arg = Py_BuildValue("N",
++                                    PyUnicode_AsUTF8String(fileFromWchar));
++#else
++                arg = Py_BuildValue("N",
++                                    PyUnicode_FromObject(fileFromWchar));
++#endif
++                if (!arg)
++                    goto error_py_fun;
++                Py_XDECREF(fileFromWchar);
++                fileFromWchar = NULL;
++                if (PyList_Append(filesList, arg))
++                    goto error_py_fun;
++                Py_XDECREF(arg);
++            }
++            /*
++            printf(
++                "[%#x] %.*S: %.*S\n",
++                handle->Handle,
++                objectTypeInfo->Name.Length / 2,
++                objectTypeInfo->Name.Buffer,
++                objectName.Length / 2,
++                objectName.Buffer
++                );
++            */
++        }
++        else
++        {
++            // Print something else.
++            /*
++            printf(
++                "[%#x] %.*S: (unnamed)\n",
++                handle->Handle,
++                objectTypeInfo->Name.Length / 2,
++                objectTypeInfo->Name.Buffer
++                );
++            */
++            ;;
++        }
++        free(objectTypeInfo);
++        free(objectNameInfo);
++        CloseHandle(dupHandle);
++    }
++    HeapFree(GetProcessHeap(), 0, handleInfo);
++    CloseHandle(processHandle);
++    return filesList;
++
++error_py_fun:
++    Py_XDECREF(arg);
++    Py_XDECREF(fileFromWchar);
++    Py_DECREF(filesList);
++    return NULL;
++}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_handles.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_handles.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,10 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include <Python.h>
++#include <windows.h>
++
++PyObject* psutil_get_open_files(long pid, HANDLE processHandle);
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_info.c	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_info.c	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,435 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ * Helper functions related to fetching process information. Used by
++ * _psutil_windows module methods.
++ */
++
++#include <Python.h>
++#include <windows.h>
++#include <Psapi.h>
++#include <tlhelp32.h>
++
++#include "security.h"
++#include "process_info.h"
++#include "ntextapi.h"
++#include "../../_psutil_common.h"
++
++
++/*
++ * A wrapper around OpenProcess setting NSP exception if process
++ * no longer exists.
++ * "pid" is the process pid, "dwDesiredAccess" is the first argument
++ * exptected by OpenProcess.
++ * Return a process handle or NULL.
++ */
++HANDLE
++psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
++{
++    HANDLE hProcess;
++    DWORD processExitCode = 0;
++
++    if (pid == 0) {
++        // otherwise we'd get NoSuchProcess
++        return AccessDenied();
++    }
++
++    hProcess = OpenProcess(dwDesiredAccess, FALSE, pid);
++    if (hProcess == NULL) {
++        if (GetLastError() == ERROR_INVALID_PARAMETER)
++            NoSuchProcess();
++        else
++            PyErr_SetFromWindowsErr(0);
++        return NULL;
++    }
++
++    // make sure the process is running
++    GetExitCodeProcess(hProcess, &processExitCode);
++    if (processExitCode == 0) {
++        NoSuchProcess();
++        CloseHandle(hProcess);
++        return NULL;
++    }
++    return hProcess;
++}
++
++
++/*
++ * Same as psutil_handle_from_pid_waccess but implicitly uses
++ * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
++ * parameter for OpenProcess.
++ */
++HANDLE
++psutil_handle_from_pid(DWORD pid) {
++    DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
++    return psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
++}
++
++
++// fetch the PEB base address from NtQueryInformationProcess()
++PVOID
++psutil_get_peb_address(HANDLE ProcessHandle)
++{
++    _NtQueryInformationProcess NtQueryInformationProcess =
++        (_NtQueryInformationProcess)GetProcAddress(
++            GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
++    PROCESS_BASIC_INFORMATION pbi;
++
++    NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
++    return pbi.PebBaseAddress;
++}
++
++
++DWORD *
++psutil_get_pids(DWORD *numberOfReturnedPIDs) {
++    // Win32 SDK says the only way to know if our process array
++    // wasn't large enough is to check the returned size and make
++    // sure that it doesn't match the size of the array.
++    // If it does we allocate a larger array and try again
++
++    // Stores the actual array
++    DWORD *procArray = NULL;
++    DWORD procArrayByteSz;
++    int procArraySz = 0;
++
++    // Stores the byte size of the returned array from enumprocesses
++    DWORD enumReturnSz = 0;
++
++    do {
++        procArraySz += 1024;
++        free(procArray);
++        procArrayByteSz = procArraySz * sizeof(DWORD);
++        procArray = malloc(procArrayByteSz);
++        if (procArray == NULL) {
++            PyErr_NoMemory();
++            return NULL;
++        }
++        if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) {
++            free(procArray);
++            PyErr_SetFromWindowsErr(0);
++            return NULL;
++        }
++    } while (enumReturnSz == procArraySz * sizeof(DWORD));
++
++    // The number of elements is the returned size / size of each element
++    *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD);
++
++    return procArray;
++}
++
++
++int
++psutil_pid_is_running(DWORD pid)
++{
++    HANDLE hProcess;
++    DWORD exitCode;
++
++    // Special case for PID 0 System Idle Process
++    if (pid == 0)
++        return 1;
++    if (pid < 0)
++        return 0;
++
++    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
++                           FALSE, pid);
++    if (NULL == hProcess) {
++        // invalid parameter is no such process
++        if (GetLastError() == ERROR_INVALID_PARAMETER) {
++            CloseHandle(hProcess);
++            return 0;
++        }
++
++        // access denied obviously means there's a process to deny access to...
++        if (GetLastError() == ERROR_ACCESS_DENIED) {
++            CloseHandle(hProcess);
++            return 1;
++        }
++
++        CloseHandle(hProcess);
++        PyErr_SetFromWindowsErr(0);
++        return -1;
++    }
++
++    if (GetExitCodeProcess(hProcess, &exitCode)) {
++        CloseHandle(hProcess);
++        return (exitCode == STILL_ACTIVE);
++    }
++
++    // access denied means there's a process there so we'll assume
++    // it's running
++    if (GetLastError() == ERROR_ACCESS_DENIED) {
++        CloseHandle(hProcess);
++        return 1;
++    }
++
++    PyErr_SetFromWindowsErr(0);
++    CloseHandle(hProcess);
++    return -1;
++}
++
++
++int
++psutil_pid_in_proclist(DWORD pid)
++{
++    DWORD *proclist = NULL;
++    DWORD numberOfReturnedPIDs;
++    DWORD i;
++
++    proclist = psutil_get_pids(&numberOfReturnedPIDs);
++    if (proclist == NULL)
++        return -1;
++    for (i = 0; i < numberOfReturnedPIDs; i++) {
++        if (pid == proclist[i]) {
++            free(proclist);
++            return 1;
++        }
++    }
++
++    free(proclist);
++    return 0;
++}
++
++
++// Check exit code from a process handle. Return FALSE on an error also
++// XXX - not used anymore
++int
++handlep_is_running(HANDLE hProcess)
++{
++    DWORD dwCode;
++
++    if (NULL == hProcess)
++        return 0;
++    if (GetExitCodeProcess(hProcess, &dwCode)) {
++        if (dwCode == STILL_ACTIVE)
++            return 1;
++    }
++    return 0;
++}
++
++
++/*
++ * returns a Python list representing the arguments for the process
++ * with given pid or NULL on error.
++ */
++PyObject *
++psutil_get_arg_list(long pid)
++{
++    int nArgs, i;
++    LPWSTR *szArglist = NULL;
++    HANDLE hProcess = NULL;
++    PVOID pebAddress;
++    PVOID rtlUserProcParamsAddress;
++    UNICODE_STRING commandLine;
++    WCHAR *commandLineContents = NULL;
++    PyObject *arg = NULL;
++    PyObject *arg_from_wchar = NULL;
++    PyObject *argList = NULL;
++
++    hProcess = psutil_handle_from_pid(pid);
++    if (hProcess == NULL)
++        return NULL;
++    pebAddress = psutil_get_peb_address(hProcess);
++
++    // get the address of ProcessParameters
++#ifdef _WIN64
++    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
++                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
++#else
++    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
++                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
++#endif
++    {
++        ////printf("Could not read the address of ProcessParameters!\n");
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    // read the CommandLine UNICODE_STRING structure
++#ifdef _WIN64
++    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
++                           &commandLine, sizeof(commandLine), NULL))
++#else
++    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
++                           &commandLine, sizeof(commandLine), NULL))
++#endif
++    {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++
++    // allocate memory to hold the command line
++    commandLineContents = (WCHAR *)malloc(commandLine.Length + 1);
++    if (commandLineContents == NULL) {
++        PyErr_NoMemory();
++        goto error;
++    }
++
++    // read the command line
++    if (!ReadProcessMemory(hProcess, commandLine.Buffer,
++                           commandLineContents, commandLine.Length, NULL))
++    {
++        PyErr_SetFromWindowsErr(0);
++        goto error;
++    }
++
++    // Null-terminate the string to prevent wcslen from returning
++    // incorrect length the length specifier is in characters, but
++    // commandLine.Length is in bytes.
++    commandLineContents[(commandLine.Length / sizeof(WCHAR))] = '\0';
++
++    // attempt tp parse the command line using Win32 API, fall back
++    // on string cmdline version otherwise
++    szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
++    if (NULL == szArglist) {
++        // failed to parse arglist
++        // encode as a UTF8 Python string object from WCHAR string
++        arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
++                                                commandLine.Length / 2);
++        if (arg_from_wchar == NULL)
++            goto error;
++#if PY_MAJOR_VERSION >= 3
++        argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
++#else
++        argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
++#endif
++        if (!argList)
++            goto error;
++    }
++    else {
++        // arglist parsed as array of UNICODE_STRING, so convert each to
++        // Python string object and add to arg list
++        argList = Py_BuildValue("[]");
++        if (argList == NULL)
++            goto error;
++        for (i = 0; i < nArgs; i++) {
++            arg_from_wchar = NULL;
++            arg = NULL;
++            arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
++                                                    wcslen(szArglist[i]));
++            if (arg_from_wchar == NULL)
++                goto error;
++#if PY_MAJOR_VERSION >= 3
++            arg = PyUnicode_FromObject(arg_from_wchar);
++#else
++            arg = PyUnicode_AsUTF8String(arg_from_wchar);
++#endif
++            if (arg == NULL)
++                goto error;
++            Py_XDECREF(arg_from_wchar);
++            if (PyList_Append(argList, arg))
++                goto error;
++            Py_XDECREF(arg);
++        }
++    }
++
++    if (szArglist != NULL)
++        LocalFree(szArglist);
++    free(commandLineContents);
++    CloseHandle(hProcess);
++    return argList;
++
++error:
++    Py_XDECREF(arg);
++    Py_XDECREF(arg_from_wchar);
++    Py_XDECREF(argList);
++    if (hProcess != NULL)
++        CloseHandle(hProcess);
++    if (commandLineContents != NULL)
++        free(commandLineContents);
++    if (szArglist != NULL)
++        LocalFree(szArglist);
++    return NULL;
++}
++
++
++#define PH_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
++#define PH_NEXT_PROCESS(Process) ( \
++   ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
++   (PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
++        ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
++   NULL)
++
++const int STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
++const int STATUS_BUFFER_TOO_SMALL = 0xC0000023L;
++
++/*
++ * Given a process PID and a PSYSTEM_PROCESS_INFORMATION structure
++ * fills the structure with various process information by using
++ * NtQuerySystemInformation.
++ * We use this as a fallback when faster functions fail with access
++ * denied. This is slower because it iterates over all processes.
++ * On success return 1, else 0 with Python exception already set.
++ */
++int
++psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
++                 PVOID *retBuffer)
++{
++    static ULONG initialBufferSize = 0x4000;
++    NTSTATUS status;
++    PVOID buffer;
++    ULONG bufferSize;
++    PSYSTEM_PROCESS_INFORMATION process;
++
++    // get NtQuerySystemInformation
++    typedef DWORD (_stdcall * NTQSI_PROC) (int, PVOID, ULONG, PULONG);
++    NTQSI_PROC NtQuerySystemInformation;
++    HINSTANCE hNtDll;
++    hNtDll = LoadLibrary(TEXT("ntdll.dll"));
++    NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
++        hNtDll, "NtQuerySystemInformation");
++
++    bufferSize = initialBufferSize;
++    buffer = malloc(bufferSize);
++    if (buffer == NULL) {
++        PyErr_NoMemory();
++        goto error;
++    }
++
++    while (TRUE) {
++        status = NtQuerySystemInformation(SystemProcessInformation, buffer,
++                                          bufferSize, &bufferSize);
++
++        if (status == STATUS_BUFFER_TOO_SMALL ||
++                status == STATUS_INFO_LENGTH_MISMATCH)
++        {
++            free(buffer);
++            buffer = malloc(bufferSize);
++            if (buffer == NULL) {
++                PyErr_NoMemory();
++                goto error;
++            }
++        }
++        else {
++            break;
++        }
++    }
++
++    if (status != 0) {
++        PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
++        goto error;
++    }
++
++    if (bufferSize <= 0x20000)
++        initialBufferSize = bufferSize;
++
++    process = PH_FIRST_PROCESS(buffer);
++    do {
++        if (process->UniqueProcessId == (HANDLE)pid) {
++            *retProcess = process;
++            *retBuffer = buffer;
++            return 1;
++        }
++    } while ( (process = PH_NEXT_PROCESS(process)) );
++
++    NoSuchProcess();
++    goto error;
++
++error:
++    FreeLibrary(hNtDll);
++    if (buffer != NULL)
++        free(buffer);
++    return 0;
++}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_info.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/process_info.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#if !defined(__PROCESS_INFO_H)
++#define __PROCESS_INFO_H
++
++#include <Python.h>
++#include <windows.h>
++#include "security.h"
++#include "ntextapi.h"
++
++DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
++HANDLE psutil_handle_from_pid(DWORD pid);
++HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
++int psutil_handlep_is_running(HANDLE hProcess);
++int psutil_pid_in_proclist(DWORD pid);
++int psutil_pid_is_running(DWORD pid);
++PVOID psutil_get_peb_address(HANDLE ProcessHandle);
++PyObject* psutil_get_arg_list(long pid);
++int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
++                         PVOID *retBuffer);
++
++#endif
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/security.c	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/security.c	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,228 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ * Security related functions for Windows platform (Set privileges such as
++ * SeDebug), as well as security helper functions.
++ */
++
++#include <windows.h>
++#include <Python.h>
++
++
++/*
++ * Convert a process handle to a process token handle.
++ */
++HANDLE
++psutil_token_from_handle(HANDLE hProcess) {
++    HANDLE hToken = NULL;
++
++    if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
++        return PyErr_SetFromWindowsErr(0);
++    return hToken;
++}
++
++
++/*
++ * http://www.ddj.com/windows/184405986
++ *
++ * There's a way to determine whether we're running under the Local System
++ * account. However (you guessed it), we have to call more Win32 functions to
++ * determine this. Backing up through the code listing, we need to make another
++ * call to GetTokenInformation, but instead of passing through the TOKEN_USER
++ * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns
++ * an array of privileges that the account has in the environment. Iterating
++ * through the array, we call the function LookupPrivilegeName looking for the
++ * string �SeTcbPrivilege. If the function returns this string, then this
++ * account has Local System privileges
++ */
++int
++psutil_has_system_privilege(HANDLE hProcess) {
++    DWORD i;
++    DWORD dwSize = 0;
++    DWORD dwRetval = 0;
++    TCHAR privName[256];
++    DWORD dwNameSize = 256;
++    // PTOKEN_PRIVILEGES tp = NULL;
++    BYTE *pBuffer = NULL;
++    TOKEN_PRIVILEGES *tp = NULL;
++    HANDLE hToken = psutil_token_from_handle(hProcess);
++
++    if (NULL == hToken)
++        return -1;
++    // call GetTokenInformation first to get the buffer size
++    if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) {
++        dwRetval = GetLastError();
++        // if it failed for a reason other than the buffer, bail out
++        if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) {
++            PyErr_SetFromWindowsErr(dwRetval);
++            return 0;
++        }
++    }
++
++    // allocate buffer and call GetTokenInformation again
++    // tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
++    pBuffer = (BYTE *) malloc(dwSize);
++    if (pBuffer == NULL) {
++        PyErr_NoMemory();
++        return -1;
++    }
++
++    if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer,
++                              dwSize, &dwSize))
++    {
++        PyErr_SetFromWindowsErr(0);
++        free(pBuffer);
++        return -1;
++    }
++
++    // convert the BYTE buffer to a TOKEN_PRIVILEGES struct pointer
++    tp = (TOKEN_PRIVILEGES *)pBuffer;
++
++    // check all the privileges looking for SeTcbPrivilege
++    for (i = 0; i < tp->PrivilegeCount; i++) {
++        // reset the buffer contents and the buffer size
++        strcpy(privName, "");
++        dwNameSize = sizeof(privName) / sizeof(TCHAR);
++        if (! LookupPrivilegeName(NULL,
++                                  &tp->Privileges[i].Luid,
++                                  (LPTSTR)privName,
++                                  &dwNameSize))
++        {
++            PyErr_SetFromWindowsErr(0);
++            free(pBuffer);
++            return -1;
++        }
++
++        // if we find the SeTcbPrivilege then it's a LocalSystem process
++        if (! lstrcmpi(privName, TEXT("SeTcbPrivilege"))) {
++            free(pBuffer);
++            return 1;
++        }
++    }
++
++    free(pBuffer);
++    return 0;
++}
++
++
++BOOL
++psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
++{
++    TOKEN_PRIVILEGES tp;
++    LUID luid;
++    TOKEN_PRIVILEGES tpPrevious;
++    DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
++
++    if (!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
++
++    // first pass.  get current privilege setting
++    tp.PrivilegeCount = 1;
++    tp.Privileges[0].Luid = luid;
++    tp.Privileges[0].Attributes = 0;
++
++    AdjustTokenPrivileges(
++        hToken,
++        FALSE,
++        &tp,
++        sizeof(TOKEN_PRIVILEGES),
++        &tpPrevious,
++        &cbPrevious
++    );
++
++    if (GetLastError() != ERROR_SUCCESS) return FALSE;
++
++    // second pass. set privilege based on previous setting
++    tpPrevious.PrivilegeCount = 1;
++    tpPrevious.Privileges[0].Luid = luid;
++
++    if (bEnablePrivilege)
++        tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
++    else
++        tpPrevious.Privileges[0].Attributes ^=
++            (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
++
++    AdjustTokenPrivileges(
++        hToken,
++        FALSE,
++        &tpPrevious,
++        cbPrevious,
++        NULL,
++        NULL
++    );
++
++    if (GetLastError() != ERROR_SUCCESS) return FALSE;
++
++    return TRUE;
++}
++
++
++int
++psutil_set_se_debug()
++{
++    HANDLE hToken;
++    if (! OpenThreadToken(GetCurrentThread(),
++                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
++                          FALSE,
++                          &hToken)
++       ) {
++        if (GetLastError() == ERROR_NO_TOKEN) {
++            if (!ImpersonateSelf(SecurityImpersonation)) {
++                CloseHandle(hToken);
++                return 0;
++            }
++            if (!OpenThreadToken(GetCurrentThread(),
++                                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
++                                 FALSE,
++                                 &hToken)
++               ) {
++                RevertToSelf();
++                CloseHandle(hToken);
++                return 0;
++            }
++        }
++    }
++
++    // enable SeDebugPrivilege (open any process)
++    if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, TRUE)) {
++        RevertToSelf();
++        CloseHandle(hToken);
++        return 0;
++    }
++
++    RevertToSelf();
++    CloseHandle(hToken);
++    return 1;
++}
++
++
++int
++psutil_unset_se_debug()
++{
++    HANDLE hToken;
++    if (! OpenThreadToken(GetCurrentThread(),
++                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
++                          FALSE,
++                          &hToken)
++       ) {
++        if (GetLastError() == ERROR_NO_TOKEN) {
++            if (! ImpersonateSelf(SecurityImpersonation))
++                return 0;
++            if (!OpenThreadToken(GetCurrentThread(),
++                                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
++                                 FALSE,
++                                 &hToken))
++            {
++                return 0;
++            }
++        }
++    }
++
++    // now disable SeDebug
++    if (! psutil_set_privilege(hToken, SE_DEBUG_NAME, FALSE))
++        return 0;
++
++    CloseHandle(hToken);
++    return 1;
++}
+--- mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/security.h	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/psutil/arch/windows/security.h	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,17 @@
++/*
++ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ *
++ * Security related functions for Windows platform (Set privileges such as
++ * SeDebug), as well as security helper functions.
++ */
++
++#include <windows.h>
++
++BOOL psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege);
++HANDLE psutil_token_from_handle(HANDLE hProcess);
++int psutil_has_system_privilege(HANDLE hProcess);
++int psutil_set_se_debug();
++int psutil_unset_se_debug();
++
+--- mozjs-24.2.0/js/src/python/psutil/psutil/error.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/psutil/error.py	1969-12-31 16:00:00.000000000 -0800
+@@ -1,19 +0,0 @@
+-#!/usr/bin/env python
+-
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+-# Use of this source code is governed by a BSD-style license that can be
+-# found in the LICENSE file.
+-
+-"""This module is deprecated as exceptions are defined in _error.py
+-and are supposed to be accessed from 'psutil' namespace as in:
+-- psutil.NoSuchProcess
+-- psutil.AccessDenied
+-- psutil.TimeoutExpired
+-"""
+-
+-import warnings
+-from psutil._error import *
+-
+-warnings.warn("psutil.error module is deprecated and scheduled for removal; " \
+-              "use psutil namespace instead", category=DeprecationWarning,
+-               stacklevel=2)
+--- mozjs-24.2.0/js/src/python/psutil/README	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/README	1969-12-31 16:00:00.000000000 -0800
+@@ -1,208 +0,0 @@
+-===========
+-Quick links
+-===========
+-
+-* `Home page <http://code.google.com/p/psutil>`_
+-* `Download <http://code.google.com/p/psutil/downloads/list>`_
+-* `Documentation <http://code.google.com/p/psutil/wiki/Documentation>`_
+-
+-=======
+-Summary
+-=======
+-
+-psutil is a module providing an interface for retrieving information on all
+-running processes and system utilization (CPU, memory, disks, network, users) in
+-a portable way by using Python, implementing many functionalities offered by
+-command line tools such as:  **ps, top, df, kill, free, lsof, free, netstat,
+-ifconfig, nice, ionice, iostat, iotop, uptime, pidof, tty, who, taskset, pmap**.
+-
+-It currently supports **Linux**, **Windows**, **OSX** and **FreeBSD** both
+-**32-bit** and **64-bit** with Python versions from **2.4** to **3.3** by using
+-a single code base.
+-
+-==============
+-Example usages
+-==============
+-
+-CPU
+-===
+-
+->>> import psutil
+->>> psutil.cpu_times()
+-cputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540,
+-         iowait=629.509, irq=0.0, softirq=19.422)
+->>>
+->>> for x in range(3):
+-...     psutil.cpu_percent(interval=1)
+-...
+-4.0
+-5.9
+-3.8
+->>>
+->>> for x in range(3):
+-...     psutil.cpu_percent(interval=1, percpu=True)
+-...
+-[4.0, 6.9]
+-[7.0, 8.5]
+-[1.2, 9.0]
+->>>
+-
+-
+-Memory
+-======
+-
+->>> psutil.virtual_memory()
+-vmem(total=8374149120L, available=2081050624L, percent=75.1, used=8074080256L,
+-     free=300068864L, active=3294920704, inactive=1361616896, buffers=529895424L,
+-     cached=1251086336)
+->>> psutil.swap_memory()
+-swap(total=2097147904L, used=296128512L, free=1801019392L, percent=14.1,
+-     sin=304193536, sout=677842944)
+->>>
+-
+-
+-Disks
+-=====
+-
+->>> psutil.disk_partitions()
+-[partition(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
+- partition(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
+->>>
+->>> psutil.disk_usage('/')
+-usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
+->>>
+->>> psutil.disk_io_counters()
+-iostat(read_count=719566, write_count=1082197, read_bytes=18626220032,
+-       write_bytes=24081764352, read_time=5023392, write_time=63199568)
+->>>
+-
+-
+-Network
+-=======
+-
+->>> psutil.network_io_counters(pernic=True)
+-{'lo': iostat(bytes_sent=799953745, bytes_recv=799953745,
+-              packets_sent=453698, packets_recv=453698),
+- 'eth0': iostat(bytes_sent=734324837, bytes_recv=4163935363,
+-                packets_sent=3605828, packets_recv=4096685)}
+->>>
+-
+-
+-Users
+-=====
+-
+->>> psutil.get_users()
+-[user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
+- user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
+->>>
+-
+-
+-Process management
+-==================
+-
+->>> import psutil
+->>> psutil.get_pid_list()
+-[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,
+-268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,
+-2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245,
+-4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358,
+-4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
+-5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
+->>>
+->>> p = psutil.Process(7055)
+->>> p.name
+-'python'
+->>> p.exe
+-'/usr/bin/python'
+->>> p.getcwd()
+-'/home/giampaolo'
+->>> p.cmdline
+-['/usr/bin/python', 'main.py']
+->>>
+->>> str(p.status)
+-'running'
+->>> p.username
+-'giampaolo'
+->>> p.create_time
+-1267551141.5019531
+->>> p.terminal
+-'/dev/pts/0'
+->>>
+->>> p.uids
+-user(real=1000, effective=1000, saved=1000)
+->>> p.gids
+-group(real=1000, effective=1000, saved=1000)
+->>>
+->>> p.get_cpu_times()
+-cputimes(user=1.02, system=0.31)
+->>> p.get_cpu_percent(interval=1.0)
+-12.1
+->>> p.get_cpu_affinity()
+-[0, 1, 2, 3]
+->>> p.set_cpu_affinity([0])
+->>>
+->>> p.get_memory_percent()
+-0.63423
+->>>
+->>> p.get_memory_info()
+-meminfo(rss=7471104, vms=68513792)
+->>> p.get_ext_memory_info()
+-meminfo(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0)
+->>> p.get_memory_maps()
+-[mmap(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
+- mmap(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
+- mmap(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0),
+- mmap(path='[heap]', rss=54653, anonymous=8192, swap=0),
+- mmap(path='[stack]', rss=1542, anonymous=166, swap=0),
+- ...]
+->>>
+->>> p.get_io_counters()
+-io(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632)
+->>>
+->>> p.get_open_files()
+-[openfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)]
+->>>
+->>> p.get_connections()
+-[connection(fd=115, family=2, type=1, local_address=('10.0.0.1', 48776),
+-            remote_address=('93.186.135.91', 80), status='ESTABLISHED'),
+- connection(fd=117, family=2, type=1, local_address=('10.0.0.1', 43761),
+-            remote_address=('72.14.234.100', 80), status='CLOSING'),
+- connection(fd=119, family=2, type=1, local_address=('10.0.0.1', 60759),
+-            remote_address=('72.14.234.104', 80), status='ESTABLISHED'),
+- connection(fd=123, family=2, type=1, local_address=('10.0.0.1', 51314),
+-            remote_address=('72.14.234.83', 443), status='SYN_SENT')]
+->>>
+->>> p.get_num_threads()
+-4
+->>> p.get_num_fds()
+-8
+->>> p.get_threads()
+-[thread(id=5234, user_time=22.5, system_time=9.2891),
+- thread(id=5235, user_time=0.0, system_time=0.0),
+- thread(id=5236, user_time=0.0, system_time=0.0),
+- thread(id=5237, user_time=0.0707, system_time=1.1)]
+->>>
+->>> p.get_num_ctx_switches()
+-amount(voluntary=78, involuntary=19)
+->>>
+->>> p.get_nice()
+-0
+->>> p.set_nice(10)
+->>>
+->>> p.suspend()
+->>> p.resume()
+->>>
+->>> p.terminate()
+->>> p.wait(timeout=3)
+-0
+->>>
+->>> psutil.test()
+-USER         PID %CPU %MEM     VSZ     RSS TTY        START    TIME  COMMAND
+-root           1  0.0  0.0   24584    2240 ?          Jun17   00:00  init
+-root           2  0.0  0.0       0       0 ?          Jun17   00:00  kthreadd
+-root           3  0.0  0.0       0       0 ?          Jun17   00:05  ksoftirqd/0
+-...
+-giampaolo  31475  0.0  0.0   20760    3024 /dev/pts/0 Jun19   00:00  python2.4
+-giampaolo  31721  0.0  2.2  773060  181896 ?          00:04   10:30  chrome
+-root       31763  0.0  0.0       0       0 ?          00:05   00:00  kworker/0:1
+->>>
+--- mozjs-24.2.0/js/src/python/psutil/README.rst	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/README.rst	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,367 @@
++.. image:: https://pypip.in/d/psutil/badge.png
++    :target: https://crate.io/packages/psutil/
++    :alt: Download this month
++
++.. image:: https://pypip.in/v/psutil/badge.png
++    :target: https://pypi.python.org/pypi/psutil/
++    :alt: Latest version
++
++.. image:: https://pypip.in/license/psutil/badge.png
++    :target: https://pypi.python.org/pypi/psutil/
++    :alt: License
++
++.. image:: https://api.travis-ci.org/giampaolo/psutil.png?branch=master
++    :target: https://travis-ci.org/giampaolo/psutil
++    :alt: Travis
++
++===========
++Quick links
++===========
++
++- `Home page <https://github.com/giampaolo/psutil>`_
++- `Documentation <http://pythonhosted.org/psutil/>`_
++- `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
++- `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_
++- `Forum <http://groups.google.com/group/psutil/topics>`_
++- `Blog <http://grodola.blogspot.com/search/label/psutil>`_
++- `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`_
++
++=======
++Summary
++=======
++
++psutil (python system and process utilities) is a cross-platform library for
++retrieving information on **running processes** and **system utilization**
++(CPU, memory, disks, network) in Python. It is useful mainly for **system
++monitoring**, **profiling and limiting process resources** and **management of
++running processes**. It implements many functionalities offered by command line
++tools such as: ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice,
++ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap. It currently supports
++**Linux, Windows, OSX, FreeBSD** and **Sun Solaris**, both **32-bit** and
++**64-bit** architectures, with Python versions from **2.6 to 3.5** (users of
++Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
++`PyPy <http://pypy.org/>`__ is also known to work.
++
++====================
++Example applications
++====================
++
++.. image:: http://psutil.googlecode.com/svn/wiki/images/top-thumb.png
++    :target: http://psutil.googlecode.com/svn/wiki/images/top.png
++    :alt: top
++
++.. image:: http://psutil.googlecode.com/svn/wiki/images/nettop-thumb.png
++    :target: http://psutil.googlecode.com/svn/wiki/images/nettop.png
++    :alt: nettop
++
++.. image:: http://psutil.googlecode.com/svn/wiki/images/iotop-thumb.png
++    :target: http://psutil.googlecode.com/svn/wiki/images/iotop.png
++    :alt: iotop
++
++See also:
++
++ * https://github.com/nicolargo/glances
++ * https://github.com/google/grr
++ * https://github.com/Jahaja/psdash
++
++==============
++Example usages
++==============
++
++CPU
++===
++
++.. code-block:: python
++
++    >>> import psutil
++    >>> psutil.cpu_times()
++    scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
++    >>>
++    >>> for x in range(3):
++    ...     psutil.cpu_percent(interval=1)
++    ...
++    4.0
++    5.9
++    3.8
++    >>>
++    >>> for x in range(3):
++    ...     psutil.cpu_percent(interval=1, percpu=True)
++    ...
++    [4.0, 6.9, 3.7, 9.2]
++    [7.0, 8.5, 2.4, 2.1]
++    [1.2, 9.0, 9.9, 7.2]
++    >>>
++    >>>
++    >>> for x in range(3):
++    ...     psutil.cpu_times_percent(interval=1, percpu=False)
++    ...
++    scputimes(user=1.5, nice=0.0, system=0.5, idle=96.5, iowait=1.5, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
++    scputimes(user=1.0, nice=0.0, system=0.0, idle=99.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
++    scputimes(user=2.0, nice=0.0, system=0.0, idle=98.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
++    >>>
++    >>> psutil.cpu_count()
++    4
++    >>> psutil.cpu_count(logical=False)
++    2
++    >>>
++
++Memory
++======
++
++.. code-block:: python
++
++    >>> psutil.virtual_memory()
++    svmem(total=8374149120, available=2081050624, percent=75.1, used=8074080256, free=300068864, active=3294920704, inactive=1361616896, buffers=529895424, cached=1251086336)
++    >>> psutil.swap_memory()
++    sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
++    >>>
++
++Disks
++=====
++
++.. code-block:: python
++
++    >>> psutil.disk_partitions()
++    [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
++     sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
++    >>>
++    >>> psutil.disk_usage('/')
++    sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
++    >>>
++    >>> psutil.disk_io_counters(perdisk=False)
++    sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568)
++    >>>
++
++Network
++=======
++
++.. code-block:: python
++
++    >>> psutil.net_io_counters(pernic=True)
++    {'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
++     'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
++    >>>
++    >>> psutil.net_connections()
++    [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
++     pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
++     pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
++     pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
++     ...]
++    >>>
++    >>> psutil.net_if_addrs()
++    {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
++            snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
++            snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
++     'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
++               snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
++               snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
++    >>>
++    >>> psutil.net_if_stats()
++    {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
++     'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
++
++Other system info
++=================
++
++.. code-block:: python
++
++    >>> psutil.users()
++    [user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
++     user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
++    >>>
++    >>> psutil.boot_time()
++    1365519115.0
++    >>>
++
++Process management
++==================
++
++.. code-block:: python
++
++    >>> import psutil
++    >>> psutil.pids()
++    [1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,
++     268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,
++     2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245,
++     4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358,
++     4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
++     5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
++    >>>
++    >>> p = psutil.Process(7055)
++    >>> p.name()
++    'python'
++    >>> p.exe()
++    '/usr/bin/python'
++    >>> p.cwd()
++    '/home/giampaolo'
++    >>> p.cmdline()
++    ['/usr/bin/python', 'main.py']
++    >>>
++    >>> p.status()
++    'running'
++    >>> p.username()
++    'giampaolo'
++    >>> p.create_time()
++    1267551141.5019531
++    >>> p.terminal()
++    '/dev/pts/0'
++    >>>
++    >>> p.uids()
++    puids(real=1000, effective=1000, saved=1000)
++    >>> p.gids()
++    pgids(real=1000, effective=1000, saved=1000)
++    >>>
++    >>> p.cpu_times()
++    pcputimes(user=1.02, system=0.31)
++    >>> p.cpu_percent(interval=1.0)
++    12.1
++    >>> p.cpu_affinity()
++    [0, 1, 2, 3]
++    >>> p.cpu_affinity([0])  # set
++    >>>
++    >>> p.memory_percent()
++    0.63423
++    >>>
++    >>> p.memory_info()
++    pmem(rss=7471104, vms=68513792)
++    >>> p.memory_info_ex()
++    extmem(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0)
++    >>> p.memory_maps()
++    [pmmap_grouped(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
++     pmmap_grouped(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
++     pmmap_grouped(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0),
++     pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0),
++     pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0),
++     ...]
++    >>>
++    >>> p.io_counters()
++    pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632)
++    >>>
++    >>> p.open_files()
++    [popenfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)]
++    >>>
++    >>> p.connections()
++    [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
++     pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
++     pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
++     pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
++    >>>
++    >>> p.num_threads()
++    4
++    >>> p.num_fds()
++    8
++    >>> p.threads()
++    [pthread(id=5234, user_time=22.5, system_time=9.2891),
++     pthread(id=5235, user_time=0.0, system_time=0.0),
++     pthread(id=5236, user_time=0.0, system_time=0.0),
++     pthread(id=5237, user_time=0.0707, system_time=1.1)]
++    >>>
++    >>> p.num_ctx_switches()
++    pctxsw(voluntary=78, involuntary=19)
++    >>>
++    >>> p.nice()
++    0
++    >>> p.nice(10)  # set
++    >>>
++    >>> p.ionice(psutil.IOPRIO_CLASS_IDLE)  # IO priority (Win and Linux only)
++    >>> p.ionice()
++    pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
++    >>>
++    >>> p.rlimit(psutil.RLIMIT_NOFILE, (5, 5))  # set resource limits (Linux only)
++    >>> p.rlimit(psutil.RLIMIT_NOFILE)
++    (5, 5)
++    >>>
++    >>> p.suspend()
++    >>> p.resume()
++    >>>
++    >>> p.terminate()
++    >>> p.wait(timeout=3)
++    0
++    >>>
++    >>> psutil.test()
++    USER         PID %CPU %MEM     VSZ     RSS TTY        START    TIME  COMMAND
++    root           1  0.0  0.0   24584    2240            Jun17   00:00  init
++    root           2  0.0  0.0       0       0            Jun17   00:00  kthreadd
++    root           3  0.0  0.0       0       0            Jun17   00:05  ksoftirqd/0
++    ...
++    giampaolo  31475  0.0  0.0   20760    3024 /dev/pts/0 Jun19   00:00  python2.4
++    giampaolo  31721  0.0  2.2  773060  181896            00:04   10:30  chrome
++    root       31763  0.0  0.0       0       0            00:05   00:00  kworker/0:1
++    >>>
++
++Further process APIs
++====================
++
++.. code-block:: python
++
++    >>> for p in psutil.process_iter():
++    ...     print(p)
++    ...
++    psutil.Process(pid=1, name='init')
++    psutil.Process(pid=2, name='kthreadd')
++    psutil.Process(pid=3, name='ksoftirqd/0')
++    ...
++    >>>
++    >>> def on_terminate(proc):
++    ...     print("process {} terminated".format(proc))
++    ...
++    >>> # waits for multiple processes to terminate
++    >>> gone, alive = psutil.wait_procs(procs_list, 3, callback=on_terminate)
++    >>>
++
++======
++Donate
++======
++
++A lot of time and effort went into making psutil as it is right now.
++If you feel psutil is useful to you or your business and want to support its future development please consider donating me (`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`_) some money.
++I only ask for a small donation, but of course I appreciate any amount.
++
++.. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif
++    :target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
++    :alt: Donate via PayPal
++
++Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <http://www.linkedin.com/in/grodola>`_.
++
++============
++Mailing list
++============
++
++http://groups.google.com/group/psutil/
++
++========
++Timeline
++========
++
++- 2015-06-18: `psutil-3.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.1.tar.gz>`_
++- 2015-06-13: `psutil-3.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.0.tar.gz>`_
++- 2015-02-02: `psutil-2.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.1.tar.gz>`_
++- 2015-01-06: `psutil-2.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.0.tar.gz>`_
++- 2014-09-26: `psutil-2.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz>`_
++- 2014-09-21: `psutil-2.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.2.tar.gz>`_
++- 2014-04-30: `psutil-2.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.1.tar.gz>`_
++- 2014-04-08: `psutil-2.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.0.tar.gz>`_
++- 2014-03-10: `psutil-2.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz>`_
++- 2013-11-25: `psutil-1.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.1.tar.gz>`_
++- 2013-11-20: `psutil-1.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.0.tar.gz>`_
++- 2013-11-07: `psutil-1.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.3.tar.gz>`_
++- 2013-10-22: `psutil-1.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.2.tar.gz>`_
++- 2013-10-08: `psutil-1.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.1.tar.gz>`_
++- 2013-09-28: `psutil-1.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.0.tar.gz>`_
++- 2013-07-12: `psutil-1.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.1.tar.gz>`_
++- 2013-07-10: `psutil-1.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.0.tar.gz>`_
++- 2013-05-03: `psutil-0.7.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.1.tar.gz>`_
++- 2013-04-12: `psutil-0.7.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.0.tar.gz>`_
++- 2012-08-16: `psutil-0.6.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.1.tar.gz>`_
++- 2012-08-13: `psutil-0.6.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.0.tar.gz>`_
++- 2012-06-29: `psutil-0.5.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.1.tar.gz>`_
++- 2012-06-27: `psutil-0.5.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.0.tar.gz>`_
++- 2011-12-14: `psutil-0.4.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.1.tar.gz>`_
++- 2011-10-29: `psutil-0.4.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.0.tar.gz>`_
++- 2011-07-08: `psutil-0.3.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.3.0.tar.gz>`_
++- 2011-03-20: `psutil-0.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.1.tar.gz>`_
++- 2010-11-13: `psutil-0.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.0.tar.gz>`_
++- 2010-03-02: `psutil-0.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.3.tar.gz>`_
++- 2009-05-06: `psutil-0.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.2.tar.gz>`_
++- 2009-03-06: `psutil-0.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.1.tar.gz>`_
++- 2009-01-27: `psutil-0.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.0.tar.gz>`_
+--- mozjs-24.2.0/js/src/python/psutil/setup.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/setup.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,22 +1,28 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009 Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+-import sys
++"""psutil is a cross-platform library for retrieving information on
++running processes and system utilization (CPU, memory, disks, network)
++in Python.
++"""
++
+ import os
++import sys
+ try:
+     from setuptools import setup, Extension
+ except ImportError:
+     from distutils.core import setup, Extension
+ 
+ 
++HERE = os.path.abspath(os.path.dirname(__file__))
++
++
+ def get_version():
+-    INIT = os.path.abspath(os.path.join(os.path.dirname(__file__),
+-                           'psutil', '__init__.py'))
+-    f = open(INIT, 'r')
+-    try:
++    INIT = os.path.join(HERE, 'psutil/__init__.py')
++    with open(INIT, 'r') as f:
+         for line in f:
+             if line.startswith('__version__'):
+                 ret = eval(line.strip().split(' = ')[1])
+@@ -26,24 +32,29 @@
+                 return ret
+         else:
+             raise ValueError("couldn't find version string")
+-    finally:
+-        f.close()
++
+ 
+ def get_description():
+-    README = os.path.abspath(os.path.join(os.path.dirname(__file__), 'README'))
+-    f = open(README, 'r')
+-    try:
++    README = os.path.join(HERE, 'README.rst')
++    with open(README, 'r') as f:
+         return f.read()
+-    finally:
+-        f.close()
++
+ 
+ VERSION = get_version()
++VERSION_MACRO = ('PSUTIL_VERSION', int(VERSION.replace('.', '')))
+ 
+ 
+ # POSIX
+ if os.name == 'posix':
+-    posix_extension = Extension('_psutil_posix',
+-                                sources = ['psutil/_psutil_posix.c'])
++    libraries = []
++    if sys.platform.startswith("sunos"):
++        libraries.append('socket')
++
++    posix_extension = Extension(
++        'psutil._psutil_posix',
++        sources=['psutil/_psutil_posix.c'],
++        libraries=libraries,
++    )
+ # Windows
+ if sys.platform.startswith("win32"):
+ 
+@@ -51,45 +62,78 @@
+         maj, min = sys.getwindowsversion()[0:2]
+         return '0x0%s' % ((maj * 100) + min)
+ 
+-    extensions = [Extension('_psutil_mswindows',
+-                            sources=['psutil/_psutil_mswindows.c',
+-                                     'psutil/_psutil_common.c',
+-                                     'psutil/arch/mswindows/process_info.c',
+-                                     'psutil/arch/mswindows/process_handles.c',
+-                                     'psutil/arch/mswindows/security.c'],
+-                            define_macros=[('_WIN32_WINNT', get_winver()),
+-                                           ('_AVAIL_WINVER_', get_winver())],
+-                            libraries=["psapi", "kernel32", "advapi32",
+-                                       "shell32", "netapi32", "iphlpapi",
+-                                       "wtsapi32"],
+-                            #extra_compile_args=["/Z7"],
+-                            #extra_link_args=["/DEBUG"]
+-                            )]
++    extensions = [Extension(
++        'psutil._psutil_windows',
++        sources=[
++            'psutil/_psutil_windows.c',
++            'psutil/_psutil_common.c',
++            'psutil/arch/windows/process_info.c',
++            'psutil/arch/windows/process_handles.c',
++            'psutil/arch/windows/security.c',
++        ],
++        define_macros=[
++            VERSION_MACRO,
++            # be nice to mingw, see:
++            # http://www.mingw.org/wiki/Use_more_recent_defined_functions
++            ('_WIN32_WINNT', get_winver()),
++            ('_AVAIL_WINVER_', get_winver()),
++            ('_CRT_SECURE_NO_WARNINGS', None),
++            # see: https://github.com/giampaolo/psutil/issues/348
++            ('PSAPI_VERSION', 1),
++        ],
++        libraries=[
++            "psapi", "kernel32", "advapi32", "shell32", "netapi32", "iphlpapi",
++            "wtsapi32", "ws2_32",
++        ],
++        # extra_compile_args=["/Z7"],
++        # extra_link_args=["/DEBUG"]
++    )]
+ # OS X
+ elif sys.platform.startswith("darwin"):
+-    extensions = [Extension('_psutil_osx',
+-                            sources = ['psutil/_psutil_osx.c',
+-                                       'psutil/_psutil_common.c',
+-                                       'psutil/arch/osx/process_info.c'],
+-                            extra_link_args=['-framework', 'CoreFoundation',
+-                                             '-framework', 'IOKit']
+-                            ),
+-                  posix_extension]
++    extensions = [Extension(
++        'psutil._psutil_osx',
++        sources=[
++            'psutil/_psutil_osx.c',
++            'psutil/_psutil_common.c',
++            'psutil/arch/osx/process_info.c'
++        ],
++        define_macros=[VERSION_MACRO],
++        extra_link_args=[
++            '-framework', 'CoreFoundation', '-framework', 'IOKit'
++        ],
++    ),
++        posix_extension,
++    ]
+ # FreeBSD
+ elif sys.platform.startswith("freebsd"):
+-    extensions = [Extension('_psutil_bsd',
+-                            sources = ['psutil/_psutil_bsd.c',
+-                                       'psutil/_psutil_common.c',
+-                                       'psutil/arch/bsd/process_info.c'],
+-                            libraries=["devstat"],
+-                            ),
+-                  posix_extension]
++    extensions = [Extension(
++        'psutil._psutil_bsd',
++        sources=[
++            'psutil/_psutil_bsd.c',
++            'psutil/_psutil_common.c',
++            'psutil/arch/bsd/process_info.c'
++        ],
++        define_macros=[VERSION_MACRO],
++        libraries=["devstat"]),
++        posix_extension,
++    ]
+ # Linux
+ elif sys.platform.startswith("linux"):
+-    extensions = [Extension('_psutil_linux',
+-                            sources=['psutil/_psutil_linux.c'],
+-                            ),
+-                  posix_extension]
++    extensions = [Extension(
++        'psutil._psutil_linux',
++        sources=['psutil/_psutil_linux.c'],
++        define_macros=[VERSION_MACRO]),
++        posix_extension,
++    ]
++# Solaris
++elif sys.platform.lower().startswith('sunos'):
++    extensions = [Extension(
++        'psutil._psutil_sunos',
++        sources=['psutil/_psutil_sunos.c'],
++        define_macros=[VERSION_MACRO],
++        libraries=['kstat', 'nsl', 'socket']),
++        posix_extension,
++    ]
+ else:
+     sys.exit('platform %s is not supported' % sys.platform)
+ 
+@@ -98,58 +142,61 @@
+     setup_args = dict(
+         name='psutil',
+         version=VERSION,
+-        download_url="http://psutil.googlecode.com/files/psutil-%s.tar.gz" \
+-                     % VERSION,
+-        description='A process and system utilities module for Python',
++        description=__doc__.replace('\n', '').strip(),
+         long_description=get_description(),
+-        keywords=['ps', 'top', 'kill', 'free', 'lsof', 'netstat', 'nice',
+-                  'tty', 'ionice', 'uptime', 'taskmgr', 'process', 'df',
+-                  'iotop', 'iostat', 'ifconfig', 'taskset', 'who', 'pidof',
+-                  'pmap', 'smem', 'monitoring',],
+-        author='Giampaolo Rodola, Jay Loden',
+-        author_email='[email protected]',
+-        maintainer='Giampaolo Rodola',
+-        maintainer_email='g.rodola <at> gmail <dot> com',
+-        url='http://code.google.com/p/psutil/',
++        keywords=[
++            'ps', 'top', 'kill', 'free', 'lsof', 'netstat', 'nice', 'tty',
++            'ionice', 'uptime', 'taskmgr', 'process', 'df', 'iotop', 'iostat',
++            'ifconfig', 'taskset', 'who', 'pidof', 'pmap', 'smem', 'pstree',
++            'monitoring', 'ulimit', 'prlimit',
++        ],
++        author='Giampaolo Rodola',
++        author_email='g.rodola <at> gmail <dot> com',
++        url='https://github.com/giampaolo/psutil',
+         platforms='Platform Independent',
+-        license='License :: OSI Approved :: BSD License',
++        license='BSD',
+         packages=['psutil'],
++        # see: python setup.py register --list-classifiers
+         classifiers=[
+-              'Development Status :: 5 - Production/Stable',
+-              'Environment :: Console',
+-              'Operating System :: MacOS :: MacOS X',
+-              'Operating System :: Microsoft',
+-              'Operating System :: Microsoft :: Windows :: Windows NT/2000',
+-              'Operating System :: POSIX',
+-              'Operating System :: POSIX :: Linux',
+-              'Operating System :: POSIX :: BSD :: FreeBSD',
+-              'Operating System :: OS Independent',
+-              'Programming Language :: C',
+-              'Programming Language :: Python',
+-              'Programming Language :: Python :: 2',
+-              'Programming Language :: Python :: 2.4',
+-              'Programming Language :: Python :: 2.5',
+-              'Programming Language :: Python :: 2.6',
+-              'Programming Language :: Python :: 2.7',
+-              'Programming Language :: Python :: 3',
+-              'Programming Language :: Python :: 3.0',
+-              'Programming Language :: Python :: 3.1',
+-              'Programming Language :: Python :: 3.2',
+-              'Programming Language :: Python :: 3.3',
+-              'Topic :: System :: Monitoring',
+-              'Topic :: System :: Networking',
+-              'Topic :: System :: Networking :: Monitoring',
+-              'Topic :: System :: Benchmark',
+-              'Topic :: System :: Hardware',
+-              'Topic :: System :: Systems Administration',
+-              'Topic :: Utilities',
+-              'Topic :: Software Development :: Libraries',
+-              'Topic :: Software Development :: Libraries :: Python Modules',
+-              'Intended Audience :: Developers',
+-              'Intended Audience :: System Administrators',
+-              'License :: OSI Approved :: BSD License',
+-              ],
+-        )
++            'Development Status :: 5 - Production/Stable',
++            'Environment :: Console',
++            'Environment :: Win32 (MS Windows)',
++            'Intended Audience :: Developers',
++            'Intended Audience :: Information Technology',
++            'Intended Audience :: System Administrators',
++            'License :: OSI Approved :: BSD License',
++            'Operating System :: MacOS :: MacOS X',
++            'Operating System :: Microsoft :: Windows :: Windows NT/2000',
++            'Operating System :: Microsoft',
++            'Operating System :: OS Independent',
++            'Operating System :: POSIX :: BSD :: FreeBSD',
++            'Operating System :: POSIX :: Linux',
++            'Operating System :: POSIX :: SunOS/Solaris',
++            'Operating System :: POSIX',
++            'Programming Language :: C',
++            'Programming Language :: Python :: 2',
++            'Programming Language :: Python :: 2.6',
++            'Programming Language :: Python :: 2.7',
++            'Programming Language :: Python :: 3',
++            'Programming Language :: Python :: 3.0',
++            'Programming Language :: Python :: 3.1',
++            'Programming Language :: Python :: 3.2',
++            'Programming Language :: Python :: 3.3',
++            'Programming Language :: Python :: 3.4',
++            'Programming Language :: Python :: Implementation :: CPython',
++            'Programming Language :: Python :: Implementation :: PyPy',
++            'Programming Language :: Python',
++            'Topic :: Software Development :: Libraries :: Python Modules',
++            'Topic :: Software Development :: Libraries',
++            'Topic :: System :: Benchmark',
++            'Topic :: System :: Hardware',
++            'Topic :: System :: Monitoring',
++            'Topic :: System :: Networking :: Monitoring',
++            'Topic :: System :: Networking',
++            'Topic :: System :: Systems Administration',
++            'Topic :: Utilities',
++        ],
++    )
+     if extensions is not None:
+         setup_args["ext_modules"] = extensions
+     setup(**setup_args)
+--- mozjs-24.2.0/js/src/python/psutil/test/_bsd.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/_bsd.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,29 +1,30 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
++# TODO: add test for comparing connections with 'sockstat' cmd
++
+ """BSD specific tests.  These are implicitly run by test_psutil.py."""
+ 
+-import unittest
++import os
+ import subprocess
+-import time
+-import re
+ import sys
+-import os
++import time
+ 
+ import psutil
+ 
+ from psutil._compat import PY3
+-from test_psutil import DEVNULL
+-from test_psutil import (reap_children, get_test_subprocess, sh, which,
+-                         skipUnless)
++from test_psutil import (TOLERANCE, BSD, sh, get_test_subprocess, which,
++                         retry_before_failing, reap_children, unittest)
+ 
+ 
+ PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+-TOLERANCE = 200 * 1024  # 200 KB
+-MUSE_AVAILABLE = which('muse')
++if os.getuid() == 0:  # muse requires root privileges
++    MUSE_AVAILABLE = which('muse')
++else:
++    MUSE_AVAILABLE = False
+ 
+ 
+ def sysctl(cmdline):
+@@ -37,9 +38,10 @@
+     except ValueError:
+         return result
+ 
++
+ def muse(field):
+     """Thin wrapper around 'muse' cmdline utility."""
+-    out = sh('muse', stderr=DEVNULL)
++    out = sh('muse')
+     for line in out.split('\n'):
+         if line.startswith(field):
+             break
+@@ -48,37 +50,32 @@
+     return int(line.split()[1])
+ 
+ 
[email protected](BSD, "not a BSD system")
+ class BSDSpecificTestCase(unittest.TestCase):
+ 
+-    def setUp(self):
+-        self.pid = get_test_subprocess().pid
++    @classmethod
++    def setUpClass(cls):
++        cls.pid = get_test_subprocess().pid
+ 
+-    def tearDown(self):
++    @classmethod
++    def tearDownClass(cls):
+         reap_children()
+ 
+-    def assert_eq_w_tol(self, first, second, tolerance):
+-        difference = abs(first - second)
+-        if difference <= tolerance:
+-            return
+-        msg = '%r != %r within %r delta (%r difference)' \
+-              % (first, second, tolerance, difference)
+-        raise AssertionError(msg)
+-
+-    def test_BOOT_TIME(self):
++    def test_boot_time(self):
+         s = sysctl('sysctl kern.boottime')
+         s = s[s.find(" sec = ") + 7:]
+         s = s[:s.find(',')]
+         btime = int(s)
+-        self.assertEqual(btime, psutil.BOOT_TIME)
++        self.assertEqual(btime, psutil.boot_time())
+ 
+     def test_process_create_time(self):
+-        cmdline = "ps -o lstart -p %s" %self.pid
++        cmdline = "ps -o lstart -p %s" % self.pid
+         p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+         output = p.communicate()[0]
+         if PY3:
+             output = str(output, sys.stdout.encoding)
+         start_ps = output.replace('STARTED', '').strip()
+-        start_psutil = psutil.Process(self.pid).create_time
++        start_psutil = psutil.Process(self.pid).create_time()
+         start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
+                                      time.localtime(start_psutil))
+         self.assertEqual(start_ps, start_psutil)
+@@ -110,9 +107,10 @@
+             if abs(usage.used - used) > 10 * 1024 * 1024:
+                 self.fail("psutil=%s, df=%s" % (usage.used, used))
+ 
++    @retry_before_failing()
+     def test_memory_maps(self):
+         out = sh('procstat -v %s' % self.pid)
+-        maps = psutil.Process(self.pid).get_memory_maps(grouped=False)
++        maps = psutil.Process(self.pid).memory_maps(grouped=False)
+         lines = out.split('\n')[1:]
+         while lines:
+             line = lines.pop()
+@@ -124,75 +122,131 @@
+             if not map.path.startswith('['):
+                 self.assertEqual(fields[10], map.path)
+ 
++    def test_exe(self):
++        out = sh('procstat -b %s' % self.pid)
++        self.assertEqual(psutil.Process(self.pid).exe(),
++                         out.split('\n')[1].split()[-1])
++
++    def test_cmdline(self):
++        out = sh('procstat -c %s' % self.pid)
++        self.assertEqual(' '.join(psutil.Process(self.pid).cmdline()),
++                         ' '.join(out.split('\n')[1].split()[2:]))
++
++    def test_uids_gids(self):
++        out = sh('procstat -s %s' % self.pid)
++        euid, ruid, suid, egid, rgid, sgid = out.split('\n')[1].split()[2:8]
++        p = psutil.Process(self.pid)
++        uids = p.uids()
++        gids = p.gids()
++        self.assertEqual(uids.real, int(ruid))
++        self.assertEqual(uids.effective, int(euid))
++        self.assertEqual(uids.saved, int(suid))
++        self.assertEqual(gids.real, int(rgid))
++        self.assertEqual(gids.effective, int(egid))
++        self.assertEqual(gids.saved, int(sgid))
++
+     # --- virtual_memory(); tests against sysctl
+ 
+     def test_vmem_total(self):
+         syst = sysctl("sysctl vm.stats.vm.v_page_count") * PAGESIZE
+         self.assertEqual(psutil.virtual_memory().total, syst)
+ 
++    @retry_before_failing()
+     def test_vmem_active(self):
+         syst = sysctl("vm.stats.vm.v_active_count") * PAGESIZE
+-        self.assert_eq_w_tol(psutil.virtual_memory().active, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().active, syst,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_inactive(self):
+         syst = sysctl("vm.stats.vm.v_inactive_count") * PAGESIZE
+-        self.assert_eq_w_tol(psutil.virtual_memory().inactive, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().inactive, syst,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_wired(self):
+         syst = sysctl("vm.stats.vm.v_wire_count") * PAGESIZE
+-        self.assert_eq_w_tol(psutil.virtual_memory().wired, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().wired, syst,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_cached(self):
+         syst = sysctl("vm.stats.vm.v_cache_count") * PAGESIZE
+-        self.assert_eq_w_tol(psutil.virtual_memory().cached, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().cached, syst,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_free(self):
+         syst = sysctl("vm.stats.vm.v_free_count") * PAGESIZE
+-        self.assert_eq_w_tol(psutil.virtual_memory().free, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().free, syst,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_buffers(self):
+         syst = sysctl("vfs.bufspace")
+-        self.assert_eq_w_tol(psutil.virtual_memory().buffers, syst, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().buffers, syst,
++                               delta=TOLERANCE)
++
++    def test_cpu_count_logical(self):
++        syst = sysctl("hw.ncpu")
++        self.assertEqual(psutil.cpu_count(logical=True), syst)
+ 
+     # --- virtual_memory(); tests against muse
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
+     def test_total(self):
+         num = muse('Total')
+         self.assertEqual(psutil.virtual_memory().total, num)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_active(self):
+         num = muse('Active')
+-        self.assert_eq_w_tol(psutil.virtual_memory().active, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().active, num,
++                               delta=TOLERANCE)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_inactive(self):
+         num = muse('Inactive')
+-        self.assert_eq_w_tol(psutil.virtual_memory().inactive, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
++                               delta=TOLERANCE)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_wired(self):
+         num = muse('Wired')
+-        self.assert_eq_w_tol(psutil.virtual_memory().wired, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().wired, num,
++                               delta=TOLERANCE)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_cached(self):
+         num = muse('Cache')
+-        self.assert_eq_w_tol(psutil.virtual_memory().cached, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().cached, num,
++                               delta=TOLERANCE)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_free(self):
+         num = muse('Free')
+-        self.assert_eq_w_tol(psutil.virtual_memory().free, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().free, num,
++                               delta=TOLERANCE)
+ 
+-    @skipUnless(MUSE_AVAILABLE)
++    @unittest.skipUnless(MUSE_AVAILABLE, "muse cmdline tool is not available")
++    @retry_before_failing()
+     def test_buffers(self):
+         num = muse('Buffer')
+-        self.assert_eq_w_tol(psutil.virtual_memory().buffers, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().buffers, num,
++                               delta=TOLERANCE)
+ 
+ 
+-if __name__ == '__main__':
++def main():
+     test_suite = unittest.TestSuite()
+     test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/_linux.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/_linux.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,37 +1,79 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """Linux specific tests.  These are implicitly run by test_psutil.py."""
+ 
+ from __future__ import division
+-import unittest
+-import subprocess
+-import sys
+-import time
++import contextlib
++import fcntl
+ import os
++import pprint
+ import re
++import socket
++import struct
++import sys
++import time
++import warnings
++
++try:
++    from unittest import mock  # py3
++except ImportError:
++    import mock  # requires "pip install mock"
++
++from test_psutil import POSIX, TOLERANCE, TRAVIS, LINUX
++from test_psutil import (skip_on_not_implemented, sh, get_test_subprocess,
++                         retry_before_failing, get_kernel_version, unittest,
++                         which)
+ 
+-from test_psutil import sh, get_test_subprocess
+-from psutil._compat import PY3
+ import psutil
++import psutil._pslinux
++from psutil._compat import PY3
+ 
+ 
+-TOLERANCE = 200 * 1024  # 200 KB
++SIOCGIFADDR = 0x8915
++SIOCGIFCONF = 0x8912
++SIOCGIFHWADDR = 0x8927
++
++
++def get_ipv4_address(ifname):
++    ifname = ifname[:15]
++    if PY3:
++        ifname = bytes(ifname, 'ascii')
++    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
++    with contextlib.closing(s):
++        return socket.inet_ntoa(
++            fcntl.ioctl(s.fileno(),
++                        SIOCGIFADDR,
++                        struct.pack('256s', ifname))[20:24])
++
++
++def get_mac_address(ifname):
++    ifname = ifname[:15]
++    if PY3:
++        ifname = bytes(ifname, 'ascii')
++    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
++    with contextlib.closing(s):
++        info = fcntl.ioctl(
++            s.fileno(), SIOCGIFHWADDR, struct.pack('256s', ifname))
++        if PY3:
++            def ord(x):
++                return x
++        else:
++            import __builtin__
++            ord = __builtin__.ord
++        return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
+ 
+ 
[email protected](LINUX, "not a Linux system")
+ class LinuxSpecificTestCase(unittest.TestCase):
+ 
+-    def assert_eq_w_tol(self, first, second, tolerance):
+-        difference = abs(first - second)
+-        if difference <= tolerance:
+-            return
+-        msg = '%r != %r within %r delta (%r difference)' \
+-              % (first, second, tolerance, difference)
+-        raise AssertionError(msg)
+-
++    @unittest.skipIf(
++        POSIX and not hasattr(os, 'statvfs'),
++        reason="os.statvfs() function not available on this platform")
++    @skip_on_not_implemented()
+     def test_disks(self):
+         # test psutil.disk_usage() and psutil.disk_partitions()
+         # against "df -a"
+@@ -61,9 +103,11 @@
+         sproc = get_test_subprocess()
+         time.sleep(1)
+         p = psutil.Process(sproc.pid)
+-        maps = p.get_memory_maps(grouped=False)
++        maps = p.memory_maps(grouped=False)
+         pmap = sh('pmap -x %s' % p.pid).split('\n')
+-        del pmap[0]; del pmap[0]  # get rid of header
++        # get rid of header
++        del pmap[0]
++        del pmap[0]
+         while maps and pmap:
+             this = maps.pop(0)
+             other = pmap.pop(0)
+@@ -79,63 +123,246 @@
+         total = int(lines[0].split()[1]) * 1024
+         self.assertEqual(total, psutil.virtual_memory().total)
+ 
++    @retry_before_failing()
+     def test_vmem_used(self):
+         lines = sh('free').split('\n')[1:]
+         used = int(lines[0].split()[2]) * 1024
+-        self.assert_eq_w_tol(used, psutil.virtual_memory().used, TOLERANCE)
++        self.assertAlmostEqual(used, psutil.virtual_memory().used,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_free(self):
+         lines = sh('free').split('\n')[1:]
+         free = int(lines[0].split()[3]) * 1024
+-        self.assert_eq_w_tol(free, psutil.virtual_memory().free, TOLERANCE)
++        self.assertAlmostEqual(free, psutil.virtual_memory().free,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_buffers(self):
+         lines = sh('free').split('\n')[1:]
+         buffers = int(lines[0].split()[5]) * 1024
+-        self.assert_eq_w_tol(buffers, psutil.virtual_memory().buffers, TOLERANCE)
++        self.assertAlmostEqual(buffers, psutil.virtual_memory().buffers,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_cached(self):
+         lines = sh('free').split('\n')[1:]
+         cached = int(lines[0].split()[6]) * 1024
+-        self.assert_eq_w_tol(cached, psutil.virtual_memory().cached, TOLERANCE)
++        self.assertAlmostEqual(cached, psutil.virtual_memory().cached,
++                               delta=TOLERANCE)
+ 
+     def test_swapmem_total(self):
+         lines = sh('free').split('\n')[1:]
+         total = int(lines[2].split()[1]) * 1024
+         self.assertEqual(total, psutil.swap_memory().total)
+ 
++    @retry_before_failing()
+     def test_swapmem_used(self):
+         lines = sh('free').split('\n')[1:]
+         used = int(lines[2].split()[2]) * 1024
+-        self.assert_eq_w_tol(used, psutil.swap_memory().used, TOLERANCE)
++        self.assertAlmostEqual(used, psutil.swap_memory().used,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_swapmem_free(self):
+         lines = sh('free').split('\n')[1:]
+         free = int(lines[2].split()[3]) * 1024
+-        self.assert_eq_w_tol(free, psutil.swap_memory().free, TOLERANCE)
++        self.assertAlmostEqual(free, psutil.swap_memory().free,
++                               delta=TOLERANCE)
+ 
++    @unittest.skipIf(TRAVIS, "unknown failure on travis")
+     def test_cpu_times(self):
+         fields = psutil.cpu_times()._fields
+-        kernel_ver = re.findall('\d.\d.\d', os.uname()[2])[0]
++        kernel_ver = re.findall('\d+\.\d+\.\d+', os.uname()[2])[0]
+         kernel_ver_info = tuple(map(int, kernel_ver.split('.')))
+-        # steal >= 2.6.11
+-        # guest >= 2.6.24
+-        # guest_nice >= 3.2.0
+         if kernel_ver_info >= (2, 6, 11):
+-            assert 'steal' in fields, fields
++            self.assertIn('steal', fields)
+         else:
+-            assert 'steal' not in fields, fields
++            self.assertNotIn('steal', fields)
+         if kernel_ver_info >= (2, 6, 24):
+-            assert 'guest' in fields, fields
++            self.assertIn('guest', fields)
+         else:
+-            assert 'guest' not in fields, fields
++            self.assertNotIn('guest', fields)
+         if kernel_ver_info >= (3, 2, 0):
+-            assert 'guest_nice' in fields, fields
++            self.assertIn('guest_nice', fields)
+         else:
+-            assert 'guest_nice' not in fields, fields
++            self.assertNotIn('guest_nice', fields)
+ 
++    def test_net_if_addrs_ips(self):
++        for name, addrs in psutil.net_if_addrs().items():
++            for addr in addrs:
++                if addr.family == psutil.AF_LINK:
++                    self.assertEqual(addr.address, get_mac_address(name))
++                elif addr.family == socket.AF_INET:
++                    self.assertEqual(addr.address, get_ipv4_address(name))
++                # TODO: test for AF_INET6 family
++
++    @unittest.skipUnless(which('ip'), "'ip' utility not available")
++    @unittest.skipIf(TRAVIS, "skipped on Travis")
++    def test_net_if_names(self):
++        out = sh("ip addr").strip()
++        nics = psutil.net_if_addrs()
++        found = 0
++        for line in out.split('\n'):
++            line = line.strip()
++            if re.search("^\d+:", line):
++                found += 1
++                name = line.split(':')[1].strip()
++                self.assertIn(name, nics.keys())
++        self.assertEqual(len(nics), found, msg="%s\n---\n%s" % (
++            pprint.pformat(nics), out))
++
++    @unittest.skipUnless(which("nproc"), "nproc utility not available")
++    def test_cpu_count_logical_w_nproc(self):
++        num = int(sh("nproc --all"))
++        self.assertEqual(psutil.cpu_count(logical=True), num)
++
++    @unittest.skipUnless(which("lscpu"), "lscpu utility not available")
++    def test_cpu_count_logical_w_lscpu(self):
++        out = sh("lscpu -p")
++        num = len([x for x in out.split('\n') if not x.startswith('#')])
++        self.assertEqual(psutil.cpu_count(logical=True), num)
++
++    # --- mocked tests
++
++    def test_virtual_memory_mocked_warnings(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            with warnings.catch_warnings(record=True) as ws:
++                warnings.simplefilter("always")
++                ret = psutil._pslinux.virtual_memory()
++                assert m.called
++                self.assertEqual(len(ws), 1)
++                w = ws[0]
++                self.assertTrue(w.filename.endswith('psutil/_pslinux.py'))
++                self.assertIn(
++                    "'cached', 'active' and 'inactive' memory stats couldn't "
++                    "be determined", str(w.message))
++                self.assertEqual(ret.cached, 0)
++                self.assertEqual(ret.active, 0)
++                self.assertEqual(ret.inactive, 0)
++
++    def test_swap_memory_mocked_warnings(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            with warnings.catch_warnings(record=True) as ws:
++                warnings.simplefilter("always")
++                ret = psutil._pslinux.swap_memory()
++                assert m.called
++                self.assertEqual(len(ws), 1)
++                w = ws[0]
++                self.assertTrue(w.filename.endswith('psutil/_pslinux.py'))
++                self.assertIn(
++                    "'sin' and 'sout' swap memory stats couldn't "
++                    "be determined", str(w.message))
++                self.assertEqual(ret.sin, 0)
++                self.assertEqual(ret.sout, 0)
++
++    def test_cpu_count_logical_mocked(self):
++        import psutil._pslinux
++        original = psutil._pslinux.cpu_count_logical()
++        with mock.patch(
++                'psutil._pslinux.os.sysconf', side_effect=ValueError) as m:
++            # Here we want to mock os.sysconf("SC_NPROCESSORS_ONLN") in
++            # order to test /proc/cpuinfo parsing.
++            # We might also test /proc/stat parsing but mocking open()
++            # like that is too difficult.
++            self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
++            assert m.called
++            # Have open() return emtpy data and make sure None is returned
++            # ('cause we want to mimick os.cpu_count())
++            with mock.patch('psutil._pslinux.open', create=True) as m:
++                self.assertIsNone(psutil._pslinux.cpu_count_logical())
++                assert m.called
++
++    def test_cpu_count_physical_mocked(self):
++        # Have open() return emtpy data and make sure None is returned
++        # ('cause we want to mimick os.cpu_count())
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertIsNone(psutil._pslinux.cpu_count_physical())
++            assert m.called
++
++    def test_proc_terminal_mocked(self):
++        with mock.patch('psutil._pslinux._psposix._get_terminal_map',
++                        return_value={}) as m:
++            self.assertIsNone(psutil._pslinux.Process(os.getpid()).terminal())
++            assert m.called
++
++    def test_proc_num_ctx_switches_mocked(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertRaises(
++                NotImplementedError,
++                psutil._pslinux.Process(os.getpid()).num_ctx_switches)
++            assert m.called
++
++    def test_proc_num_threads_mocked(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertRaises(
++                NotImplementedError,
++                psutil._pslinux.Process(os.getpid()).num_threads)
++            assert m.called
++
++    def test_proc_ppid_mocked(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertRaises(
++                NotImplementedError,
++                psutil._pslinux.Process(os.getpid()).ppid)
++            assert m.called
++
++    def test_proc_uids_mocked(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertRaises(
++                NotImplementedError,
++                psutil._pslinux.Process(os.getpid()).uids)
++            assert m.called
++
++    def test_proc_gids_mocked(self):
++        with mock.patch('psutil._pslinux.open', create=True) as m:
++            self.assertRaises(
++                NotImplementedError,
++                psutil._pslinux.Process(os.getpid()).gids)
++            assert m.called
++
++    # --- tests for specific kernel versions
++
++    @unittest.skipUnless(
++        get_kernel_version() >= (2, 6, 36),
++        "prlimit() not available on this Linux kernel version")
++    def test_prlimit_availability(self):
++        # prlimit() should be available starting from kernel 2.6.36
++        p = psutil.Process(os.getpid())
++        p.rlimit(psutil.RLIMIT_NOFILE)
++        # if prlimit() is supported *at least* these constants should
++        # be available
++        self.assertTrue(hasattr(psutil, "RLIM_INFINITY"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_AS"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_CORE"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_CPU"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_DATA"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_FSIZE"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_LOCKS"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_MEMLOCK"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_NOFILE"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_NPROC"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_RSS"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_STACK"))
++
++    @unittest.skipUnless(
++        get_kernel_version() >= (3, 0),
++        "prlimit constants not available on this Linux kernel version")
++    def test_resource_consts_kernel_v(self):
++        # more recent constants
++        self.assertTrue(hasattr(psutil, "RLIMIT_MSGQUEUE"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_NICE"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_RTPRIO"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_RTTIME"))
++        self.assertTrue(hasattr(psutil, "RLIMIT_SIGPENDING"))
+ 
+-if __name__ == '__main__':
++
++def main():
+     test_suite = unittest.TestSuite()
+     test_suite.addTest(unittest.makeSuite(LinuxSpecificTestCase))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/_osx.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/_osx.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,26 +1,25 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """OSX specific tests.  These are implicitly run by test_psutil.py."""
+ 
+-import unittest
+-import subprocess
+-import time
+-import sys
+ import os
+ import re
++import subprocess
++import sys
++import time
+ 
+ import psutil
+ 
+ from psutil._compat import PY3
+-from test_psutil import reap_children, get_test_subprocess, sh
++from test_psutil import (TOLERANCE, OSX, sh, get_test_subprocess,
++                         reap_children, retry_before_failing, unittest)
+ 
+ 
+ PAGESIZE = os.sysconf("SC_PAGE_SIZE")
+-TOLERANCE = 500 * 1024  # 500 KB
+ 
+ 
+ def sysctl(cmdline):
+@@ -36,6 +35,7 @@
+     except ValueError:
+         return result
+ 
++
+ def vm_stat(field):
+     """Wrapper around 'vm_stat' cmdline utility."""
+     out = sh('vm_stat')
+@@ -47,30 +47,25 @@
+     return int(re.search('\d+', line).group(0)) * PAGESIZE
+ 
+ 
[email protected](OSX, "not an OSX system")
+ class OSXSpecificTestCase(unittest.TestCase):
+ 
+-    def setUp(self):
+-        self.pid = get_test_subprocess().pid
++    @classmethod
++    def setUpClass(cls):
++        cls.pid = get_test_subprocess().pid
+ 
+-    def tearDown(self):
++    @classmethod
++    def tearDownClass(cls):
+         reap_children()
+ 
+-    def assert_eq_w_tol(self, first, second, tolerance):
+-        difference = abs(first - second)
+-        if difference <= tolerance:
+-            return
+-        msg = '%r != %r (tolerance=%r, difference=%s)' \
+-              % (first, second, tolerance, difference)
+-        raise AssertionError(msg)
+-
+     def test_process_create_time(self):
+-        cmdline = "ps -o lstart -p %s" %self.pid
++        cmdline = "ps -o lstart -p %s" % self.pid
+         p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
+         output = p.communicate()[0]
+         if PY3:
+             output = str(output, sys.stdout.encoding)
+         start_ps = output.replace('STARTED', '').strip()
+-        start_psutil = psutil.Process(self.pid).create_time
++        start_psutil = psutil.Process(self.pid).create_time()
+         start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
+                                      time.localtime(start_psutil))
+         self.assertEqual(start_ps, start_psutil)
+@@ -106,23 +101,31 @@
+ 
+     def test_vmem_total(self):
+         sysctl_hwphymem = sysctl('sysctl hw.memsize')
+-        self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM)
++        self.assertEqual(sysctl_hwphymem, psutil.virtual_memory().total)
+ 
++    @retry_before_failing()
+     def test_vmem_free(self):
+         num = vm_stat("free")
+-        self.assert_eq_w_tol(psutil.virtual_memory().free, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().free, num,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_active(self):
+         num = vm_stat("active")
+-        self.assert_eq_w_tol(psutil.virtual_memory().active, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().active, num,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_inactive(self):
+         num = vm_stat("inactive")
+-        self.assert_eq_w_tol(psutil.virtual_memory().inactive, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
++                               delta=TOLERANCE)
+ 
++    @retry_before_failing()
+     def test_vmem_wired(self):
+         num = vm_stat("wired")
+-        self.assert_eq_w_tol(psutil.virtual_memory().wired, num, TOLERANCE)
++        self.assertAlmostEqual(psutil.virtual_memory().wired, num,
++                               delta=TOLERANCE)
+ 
+     # --- swap mem
+ 
+@@ -146,7 +149,12 @@
+         self.assertEqual(tot1, tot2)
+ 
+ 
+-if __name__ == '__main__':
++def main():
+     test_suite = unittest.TestSuite()
+     test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/_posix.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/_posix.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,23 +1,24 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """POSIX specific tests.  These are implicitly run by test_psutil.py."""
+ 
+-import unittest
++import datetime
++import os
+ import subprocess
+-import time
+ import sys
+-import os
+-import datetime
++import time
+ 
+ import psutil
+ 
+-from psutil._compat import PY3
+-from test_psutil import (get_test_subprocess, reap_children, PYTHON, LINUX, OSX,
+-                         BSD, skip_on_access_denied, sh, skipIf)
++from psutil._compat import PY3, callable
++from test_psutil import LINUX, SUNOS, OSX, BSD, PYTHON, POSIX
++from test_psutil import (get_test_subprocess, skip_on_access_denied,
++                         retry_before_failing, reap_children, sh, unittest,
++                         get_kernel_version, wait_for_pid)
+ 
+ 
+ def ps(cmd):
+@@ -26,87 +27,104 @@
+     """
+     if not LINUX:
+         cmd = cmd.replace(" --no-headers ", " ")
++    if SUNOS:
++        cmd = cmd.replace("-o command", "-o comm")
++        cmd = cmd.replace("-o start", "-o stime")
+     p = subprocess.Popen(cmd, shell=1, stdout=subprocess.PIPE)
+     output = p.communicate()[0].strip()
+     if PY3:
+         output = str(output, sys.stdout.encoding)
+     if not LINUX:
+-        output = output.split('\n')[1]
++        output = output.split('\n')[1].strip()
+     try:
+         return int(output)
+     except ValueError:
+         return output
+ 
+ 
[email protected](POSIX, "not a POSIX system")
+ class PosixSpecificTestCase(unittest.TestCase):
+     """Compare psutil results against 'ps' command line utility."""
+ 
+-    # for ps -o arguments see: http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
+-
+-    def setUp(self):
+-        self.pid = get_test_subprocess([PYTHON, "-E", "-O"],
+-                                       stdin=subprocess.PIPE).pid
++    @classmethod
++    def setUpClass(cls):
++        cls.pid = get_test_subprocess([PYTHON, "-E", "-O"],
++                                      stdin=subprocess.PIPE).pid
++        wait_for_pid(cls.pid)
+ 
+-    def tearDown(self):
++    @classmethod
++    def tearDownClass(cls):
+         reap_children()
+ 
++    # for ps -o arguments see: http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
++
+     def test_process_parent_pid(self):
+-        ppid_ps = ps("ps --no-headers -o ppid -p %s" %self.pid)
+-        ppid_psutil = psutil.Process(self.pid).ppid
++        ppid_ps = ps("ps --no-headers -o ppid -p %s" % self.pid)
++        ppid_psutil = psutil.Process(self.pid).ppid()
+         self.assertEqual(ppid_ps, ppid_psutil)
+ 
+     def test_process_uid(self):
+-        uid_ps = ps("ps --no-headers -o uid -p %s" %self.pid)
+-        uid_psutil = psutil.Process(self.pid).uids.real
++        uid_ps = ps("ps --no-headers -o uid -p %s" % self.pid)
++        uid_psutil = psutil.Process(self.pid).uids().real
+         self.assertEqual(uid_ps, uid_psutil)
+ 
+     def test_process_gid(self):
+-        gid_ps = ps("ps --no-headers -o rgid -p %s" %self.pid)
+-        gid_psutil = psutil.Process(self.pid).gids.real
++        gid_ps = ps("ps --no-headers -o rgid -p %s" % self.pid)
++        gid_psutil = psutil.Process(self.pid).gids().real
+         self.assertEqual(gid_ps, gid_psutil)
+ 
+     def test_process_username(self):
+-        username_ps = ps("ps --no-headers -o user -p %s" %self.pid)
+-        username_psutil = psutil.Process(self.pid).username
++        username_ps = ps("ps --no-headers -o user -p %s" % self.pid)
++        username_psutil = psutil.Process(self.pid).username()
+         self.assertEqual(username_ps, username_psutil)
+ 
+     @skip_on_access_denied()
++    @retry_before_failing()
+     def test_process_rss_memory(self):
+         # give python interpreter some time to properly initialize
+         # so that the results are the same
+         time.sleep(0.1)
+-        rss_ps = ps("ps --no-headers -o rss -p %s" %self.pid)
+-        rss_psutil = psutil.Process(self.pid).get_memory_info()[0] / 1024
++        rss_ps = ps("ps --no-headers -o rss -p %s" % self.pid)
++        rss_psutil = psutil.Process(self.pid).memory_info()[0] / 1024
+         self.assertEqual(rss_ps, rss_psutil)
+ 
+     @skip_on_access_denied()
++    @retry_before_failing()
+     def test_process_vsz_memory(self):
+         # give python interpreter some time to properly initialize
+         # so that the results are the same
+         time.sleep(0.1)
+-        vsz_ps = ps("ps --no-headers -o vsz -p %s" %self.pid)
+-        vsz_psutil = psutil.Process(self.pid).get_memory_info()[1] / 1024
++        vsz_ps = ps("ps --no-headers -o vsz -p %s" % self.pid)
++        vsz_psutil = psutil.Process(self.pid).memory_info()[1] / 1024
+         self.assertEqual(vsz_ps, vsz_psutil)
+ 
+     def test_process_name(self):
+         # use command + arg since "comm" keyword not supported on all platforms
+-        name_ps = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
++        name_ps = ps("ps --no-headers -o command -p %s" % (
++            self.pid)).split(' ')[0]
+         # remove path if there is any, from the command
+         name_ps = os.path.basename(name_ps).lower()
+-        name_psutil = psutil.Process(self.pid).name.lower()
++        name_psutil = psutil.Process(self.pid).name().lower()
+         self.assertEqual(name_ps, name_psutil)
+ 
+-    @skipIf(OSX or BSD)
++    @unittest.skipIf(OSX or BSD,
++                     'ps -o start not available')
+     def test_process_create_time(self):
+-        time_ps = ps("ps --no-headers -o start -p %s" %self.pid).split(' ')[0]
+-        time_psutil = psutil.Process(self.pid).create_time
+-        time_psutil = datetime.datetime.fromtimestamp(
+-                        time_psutil).strftime("%H:%M:%S")
+-        self.assertEqual(time_ps, time_psutil)
++        time_ps = ps("ps --no-headers -o start -p %s" % self.pid).split(' ')[0]
++        time_psutil = psutil.Process(self.pid).create_time()
++        time_psutil_tstamp = datetime.datetime.fromtimestamp(
++            time_psutil).strftime("%H:%M:%S")
++        # sometimes ps shows the time rounded up instead of down, so we check
++        # for both possible values
++        round_time_psutil = round(time_psutil)
++        round_time_psutil_tstamp = datetime.datetime.fromtimestamp(
++            round_time_psutil).strftime("%H:%M:%S")
++        self.assertIn(time_ps, [time_psutil_tstamp, round_time_psutil_tstamp])
+ 
+     def test_process_exe(self):
+-        ps_pathname = ps("ps --no-headers -o command -p %s" %self.pid).split(' ')[0]
+-        psutil_pathname = psutil.Process(self.pid).exe
++        ps_pathname = ps("ps --no-headers -o command -p %s" %
++                         self.pid).split(' ')[0]
++        psutil_pathname = psutil.Process(self.pid).exe()
+         try:
+             self.assertEqual(ps_pathname, psutil_pathname)
+         except AssertionError:
+@@ -120,26 +138,33 @@
+             self.assertEqual(ps_pathname, adjusted_ps_pathname)
+ 
+     def test_process_cmdline(self):
+-        ps_cmdline = ps("ps --no-headers -o command -p %s" %self.pid)
+-        psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline)
++        ps_cmdline = ps("ps --no-headers -o command -p %s" % self.pid)
++        psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline())
++        if SUNOS:
++            # ps on Solaris only shows the first part of the cmdline
++            psutil_cmdline = psutil_cmdline.split(" ")[0]
+         self.assertEqual(ps_cmdline, psutil_cmdline)
+ 
+-    def test_get_pids(self):
++    @retry_before_failing()
++    def test_pids(self):
+         # Note: this test might fail if the OS is starting/killing
+         # other processes in the meantime
+-        p = get_test_subprocess(["ps", "ax", "-o", "pid"], stdout=subprocess.PIPE)
++        if SUNOS:
++            cmd = ["ps", "ax"]
++        else:
++            cmd = ["ps", "ax", "-o", "pid"]
++        p = get_test_subprocess(cmd, stdout=subprocess.PIPE)
+         output = p.communicate()[0].strip()
+         if PY3:
+             output = str(output, sys.stdout.encoding)
+-        output = output.replace('PID', '')
+-        p.wait()
+         pids_ps = []
+-        for pid in output.split('\n'):
+-            if pid:
+-                pids_ps.append(int(pid.strip()))
++        for line in output.split('\n')[1:]:
++            if line:
++                pid = int(line.split()[0].strip())
++                pids_ps.append(pid)
+         # remove ps subprocess pid which is supposed to be dead in meantime
+         pids_ps.remove(p.pid)
+-        pids_psutil = psutil.get_pid_list()
++        pids_psutil = psutil.pids()
+         pids_ps.sort()
+         pids_psutil.sort()
+ 
+@@ -152,30 +177,79 @@
+                          [x for x in pids_ps if x not in pids_psutil]
+             self.fail("difference: " + str(difference))
+ 
++    # for some reason ifconfig -a does not report differente interfaces
++    # psutil does
++    @unittest.skipIf(SUNOS, "test not reliable on SUNOS")
+     def test_nic_names(self):
+         p = subprocess.Popen("ifconfig -a", shell=1, stdout=subprocess.PIPE)
+         output = p.communicate()[0].strip()
+         if PY3:
+             output = str(output, sys.stdout.encoding)
+-        for nic in psutil.network_io_counters(pernic=True).keys():
++        for nic in psutil.net_io_counters(pernic=True).keys():
+             for line in output.split():
+                 if line.startswith(nic):
+                     break
+             else:
+                 self.fail("couldn't find %s nic in 'ifconfig -a' output" % nic)
+ 
+-    def test_get_users(self):
++    @retry_before_failing()
++    def test_users(self):
+         out = sh("who")
+         lines = out.split('\n')
+         users = [x.split()[0] for x in lines]
+-        self.assertEqual(len(users), len(psutil.get_users()))
++        self.assertEqual(len(users), len(psutil.users()))
+         terminals = [x.split()[1] for x in lines]
+-        for u in psutil.get_users():
++        for u in psutil.users():
+             self.assertTrue(u.name in users, u.name)
+             self.assertTrue(u.terminal in terminals, u.terminal)
+ 
++    def test_fds_open(self):
++        # Note: this fails from time to time; I'm keen on thinking
++        # it doesn't mean something is broken
++        def call(p, attr):
++            args = ()
++            attr = getattr(p, name, None)
++            if attr is not None and callable(attr):
++                if name == 'rlimit':
++                    args = (psutil.RLIMIT_NOFILE,)
++                attr(*args)
++            else:
++                attr
+ 
+-if __name__ == '__main__':
++        p = psutil.Process(os.getpid())
++        failures = []
++        ignored_names = ['terminate', 'kill', 'suspend', 'resume', 'nice',
++                         'send_signal', 'wait', 'children', 'as_dict']
++        if LINUX and get_kernel_version() < (2, 6, 36):
++            ignored_names.append('rlimit')
++        if LINUX and get_kernel_version() < (2, 6, 23):
++            ignored_names.append('num_ctx_switches')
++        for name in dir(psutil.Process):
++            if (name.startswith('_') or name in ignored_names):
++                continue
++            else:
++                try:
++                    num1 = p.num_fds()
++                    for x in range(2):
++                        call(p, name)
++                    num2 = p.num_fds()
++                except psutil.AccessDenied:
++                    pass
++                else:
++                    if abs(num2 - num1) > 1:
++                        fail = "failure while processing Process.%s method " \
++                               "(before=%s, after=%s)" % (name, num1, num2)
++                        failures.append(fail)
++        if failures:
++            self.fail('\n' + '\n'.join(failures))
++
++
++def main():
+     test_suite = unittest.TestSuite()
+     test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/_sunos.py	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/test/_sunos.py	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,48 @@
++#!/usr/bin/env python
++
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
++# Use of this source code is governed by a BSD-style license that can be
++# found in the LICENSE file.
++
++"""Sun OS specific tests.  These are implicitly run by test_psutil.py."""
++
++import sys
++import os
++
++from test_psutil import SUNOS, sh, unittest
++import psutil
++
++
[email protected](SUNOS, "not a SunOS system")
++class SunOSSpecificTestCase(unittest.TestCase):
++
++    def test_swap_memory(self):
++        out = sh('env PATH=/usr/sbin:/sbin:%s swap -l -k' % os.environ['PATH'])
++        lines = out.strip().split('\n')[1:]
++        if not lines:
++            raise ValueError('no swap device(s) configured')
++        total = free = 0
++        for line in lines:
++            line = line.split()
++            t, f = line[-2:]
++            t = t.replace('K', '')
++            f = f.replace('K', '')
++            total += int(int(t) * 1024)
++            free += int(int(f) * 1024)
++        used = total - free
++
++        psutil_swap = psutil.swap_memory()
++        self.assertEqual(psutil_swap.total, total)
++        self.assertEqual(psutil_swap.used, used)
++        self.assertEqual(psutil_swap.free, free)
++
++
++def main():
++    test_suite = unittest.TestSuite()
++    test_suite.addTest(unittest.makeSuite(SunOSSpecificTestCase))
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/_windows.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/_windows.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,51 +1,62 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """Windows specific tests.  These are implicitly run by test_psutil.py."""
+ 
++import errno
+ import os
+-import unittest
+ import platform
+ import signal
+-import time
+-import warnings
+-import atexit
+-import sys
+ import subprocess
+-import errno
++import sys
++import time
+ import traceback
+ 
+-import psutil
+-import _psutil_mswindows
+-from psutil._compat import PY3, callable, long
+-from test_psutil import reap_children, get_test_subprocess, wait_for_pid, warn
++from test_psutil import WINDOWS, get_test_subprocess, reap_children, unittest
++
+ try:
+     import wmi
+ except ImportError:
+-    err = sys.exc_info()[1]
+-    atexit.register(warn, "Couldn't run wmi tests: %s" % str(err))
+     wmi = None
+ try:
+     import win32api
+     import win32con
+ except ImportError:
+-    err = sys.exc_info()[1]
+-    atexit.register(warn, "Couldn't run pywin32 tests: %s" % str(err))
+-    win32api = None
++    win32api = win32con = None
+ 
++from psutil._compat import PY3, callable, long
++import psutil
++
++
++cext = psutil._psplatform.cext
++
++
++def wrap_exceptions(fun):
++    def wrapper(self, *args, **kwargs):
++        try:
++            return fun(self, *args, **kwargs)
++        except OSError as err:
++            from psutil._pswindows import ACCESS_DENIED_SET
++            if err.errno in ACCESS_DENIED_SET:
++                raise psutil.AccessDenied(None, None)
++            if err.errno == errno.ESRCH:
++                raise psutil.NoSuchProcess(None, None)
++            raise
++    return wrapper
+ 
+ 
[email protected](WINDOWS, "not a Windows system")
+ class WindowsSpecificTestCase(unittest.TestCase):
+ 
+-    def setUp(self):
+-        sproc = get_test_subprocess()
+-        wait_for_pid(sproc.pid)
+-        self.pid = sproc.pid
++    @classmethod
++    def setUpClass(cls):
++        cls.pid = get_test_subprocess().pid
+ 
+-    def tearDown(self):
++    @classmethod
++    def tearDownClass(cls):
+         reap_children()
+ 
+     def test_issue_24(self):
+@@ -54,14 +65,14 @@
+ 
+     def test_special_pid(self):
+         p = psutil.Process(4)
+-        self.assertEqual(p.name, 'System')
++        self.assertEqual(p.name(), 'System')
+         # use __str__ to access all common Process properties to check
+         # that nothing strange happens
+         str(p)
+-        p.username
+-        self.assertTrue(p.create_time >= 0.0)
++        p.username()
++        self.assertTrue(p.create_time() >= 0.0)
+         try:
+-            rss, vms = p.get_memory_info()
++            rss, vms = p.memory_info()
+         except psutil.AccessDenied:
+             # expected on Windows Vista and Windows 7
+             if not platform.uname()[1] in ('vista', 'win-7', 'win7'):
+@@ -69,7 +80,7 @@
+         else:
+             self.assertTrue(rss > 0)
+ 
+-    def test_signal(self):
++    def test_send_signal(self):
+         p = psutil.Process(self.pid)
+         self.assertRaises(ValueError, p.send_signal, signal.SIGINT)
+ 
+@@ -78,209 +89,210 @@
+         out = p.communicate()[0]
+         if PY3:
+             out = str(out, sys.stdout.encoding)
+-        nics = psutil.network_io_counters(pernic=True).keys()
++        nics = psutil.net_io_counters(pernic=True).keys()
+         for nic in nics:
+             if "pseudo-interface" in nic.replace(' ', '-').lower():
+                 continue
+             if nic not in out:
+-                self.fail("%r nic wasn't found in 'ipconfig /all' output" % nic)
++                self.fail(
++                    "%r nic wasn't found in 'ipconfig /all' output" % nic)
+ 
+     def test_exe(self):
+         for p in psutil.process_iter():
+             try:
+-                self.assertEqual(os.path.basename(p.exe), p.name)
++                self.assertEqual(os.path.basename(p.exe()), p.name())
+             except psutil.Error:
+                 pass
+ 
+-    if wmi is not None:
+-
+-        # --- Process class tests
++    # --- Process class tests
+ 
+-        def test_process_name(self):
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            self.assertEqual(p.name, w.Caption)
+-
+-        def test_process_exe(self):
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            self.assertEqual(p.exe, w.ExecutablePath)
+-
+-        def test_process_cmdline(self):
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            self.assertEqual(' '.join(p.cmdline), w.CommandLine.replace('"', ''))
+-
+-        def test_process_username(self):
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            domain, _, username = w.GetOwner()
+-            username = "%s\\%s" %(domain, username)
+-            self.assertEqual(p.username, username)
+-
+-        def test_process_rss_memory(self):
+-            time.sleep(0.1)
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            rss = p.get_memory_info().rss
+-            self.assertEqual(rss, int(w.WorkingSetSize))
+-
+-        def test_process_vms_memory(self):
+-            time.sleep(0.1)
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            vms = p.get_memory_info().vms
+-            # http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx
+-            # ...claims that PageFileUsage is represented in Kilo
+-            # bytes but funnily enough on certain platforms bytes are
+-            # returned instead.
+-            wmi_usage = int(w.PageFileUsage)
+-            if (vms != wmi_usage) and (vms != wmi_usage * 1024):
+-                self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms))
+-
+-        def test_process_create_time(self):
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(self.pid)
+-            wmic_create = str(w.CreationDate.split('.')[0])
+-            psutil_create = time.strftime("%Y%m%d%H%M%S",
+-                                          time.localtime(p.create_time))
+-            self.assertEqual(wmic_create, psutil_create)
+-
+-
+-        # --- psutil namespace functions and constants tests
+-
+-        def test_NUM_CPUS(self):
+-            num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
+-            self.assertEqual(num_cpus, psutil.NUM_CPUS)
+-
+-        def test_TOTAL_PHYMEM(self):
+-            w = wmi.WMI().Win32_ComputerSystem()[0]
+-            self.assertEqual(int(w.TotalPhysicalMemory), psutil.TOTAL_PHYMEM)
+-
+-        def test__UPTIME(self):
+-            # _UPTIME constant is not public but it is used internally
+-            # as value to return for pid 0 creation time.
+-            # WMI behaves the same.
+-            w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
+-            p = psutil.Process(0)
+-            wmic_create = str(w.CreationDate.split('.')[0])
+-            psutil_create = time.strftime("%Y%m%d%H%M%S",
+-                                          time.localtime(p.create_time))
+-            # XXX - ? no actual test here
+-
+-        def test_get_pids(self):
+-            # Note: this test might fail if the OS is starting/killing
+-            # other processes in the meantime
+-            w = wmi.WMI().Win32_Process()
+-            wmi_pids = [x.ProcessId for x in w]
+-            wmi_pids.sort()
+-            psutil_pids = psutil.get_pid_list()
+-            psutil_pids.sort()
+-            if wmi_pids != psutil_pids:
+-                difference = filter(lambda x:x not in wmi_pids, psutil_pids) + \
+-                             filter(lambda x:x not in psutil_pids, wmi_pids)
+-                self.fail("difference: " + str(difference))
+-
+-        def test_disks(self):
+-            ps_parts = psutil.disk_partitions(all=True)
+-            wmi_parts = wmi.WMI().Win32_LogicalDisk()
+-            for ps_part in ps_parts:
+-                for wmi_part in wmi_parts:
+-                    if ps_part.device.replace('\\', '') == wmi_part.DeviceID:
+-                        if not ps_part.mountpoint:
+-                            # this is usually a CD-ROM with no disk inserted
+-                            break
+-                        try:
+-                            usage = psutil.disk_usage(ps_part.mountpoint)
+-                        except OSError:
+-                            err = sys.exc_info()[1]
+-                            if err.errno == errno.ENOENT:
+-                                # usually this is the floppy
+-                                break
+-                            else:
+-                                raise
+-                        self.assertEqual(usage.total, int(wmi_part.Size))
+-                        wmi_free = int(wmi_part.FreeSpace)
+-                        self.assertEqual(usage.free, wmi_free)
+-                        # 10 MB tollerance
+-                        if abs(usage.free - wmi_free) > 10 * 1024 * 1024:
+-                            self.fail("psutil=%s, wmi=%s" % usage.free, wmi_free)
+-                        break
+-                else:
+-                    self.fail("can't find partition %s" % repr(ps_part))
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_name(self):
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        self.assertEqual(p.name(), w.Caption)
+ 
+-    if win32api is not None:
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_exe(self):
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        # Note: wmi reports the exe as a lower case string.
++        # Being Windows paths case-insensitive we ignore that.
++        self.assertEqual(p.exe().lower(), w.ExecutablePath.lower())
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_cmdline(self):
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        self.assertEqual(' '.join(p.cmdline()),
++                         w.CommandLine.replace('"', ''))
+ 
+-        def test_get_num_handles(self):
+-            p = psutil.Process(os.getpid())
+-            before = p.get_num_handles()
+-            handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
+-                                          win32con.FALSE, os.getpid())
+-            after = p.get_num_handles()
+-            self.assertEqual(after, before+1)
+-            win32api.CloseHandle(handle)
+-            self.assertEqual(p.get_num_handles(), before)
+-
+-        def test_get_num_handles_2(self):
+-            # Note: this fails from time to time; I'm keen on thinking
+-            # it doesn't mean something is broken
+-            def call(p, attr):
+-                attr = getattr(p, name, None)
+-                if attr is not None and callable(attr):
+-                    ret = attr()
+-                else:
+-                    ret = attr
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_username(self):
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        domain, _, username = w.GetOwner()
++        username = "%s\\%s" % (domain, username)
++        self.assertEqual(p.username(), username)
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_rss_memory(self):
++        time.sleep(0.1)
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        rss = p.memory_info().rss
++        self.assertEqual(rss, int(w.WorkingSetSize))
+ 
+-            p = psutil.Process(self.pid)
+-            attrs = []
+-            failures = []
+-            for name in dir(psutil.Process):
+-                if name.startswith('_') \
+-                or name.startswith('set_') \
+-                or name in ('terminate', 'kill', 'suspend', 'resume', 'nice',
+-                            'send_signal', 'wait', 'get_children', 'as_dict'):
+-                    continue
+-                else:
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_vms_memory(self):
++        time.sleep(0.1)
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        vms = p.memory_info().vms
++        # http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx
++        # ...claims that PageFileUsage is represented in Kilo
++        # bytes but funnily enough on certain platforms bytes are
++        # returned instead.
++        wmi_usage = int(w.PageFileUsage)
++        if (vms != wmi_usage) and (vms != wmi_usage * 1024):
++            self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms))
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_process_create_time(self):
++        w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++        p = psutil.Process(self.pid)
++        wmic_create = str(w.CreationDate.split('.')[0])
++        psutil_create = time.strftime("%Y%m%d%H%M%S",
++                                      time.localtime(p.create_time()))
++        self.assertEqual(wmic_create, psutil_create)
++
++    # --- psutil namespace functions and constants tests
++
++    @unittest.skipUnless('NUMBER_OF_PROCESSORS' in os.environ,
++                         'NUMBER_OF_PROCESSORS env var is not available')
++    def test_cpu_count(self):
++        num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
++        self.assertEqual(num_cpus, psutil.cpu_count())
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_total_phymem(self):
++        w = wmi.WMI().Win32_ComputerSystem()[0]
++        self.assertEqual(int(w.TotalPhysicalMemory),
++                         psutil.virtual_memory().total)
++
++    # @unittest.skipIf(wmi is None, "wmi module is not installed")
++    # def test__UPTIME(self):
++    #     # _UPTIME constant is not public but it is used internally
++    #     # as value to return for pid 0 creation time.
++    #     # WMI behaves the same.
++    #     w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
++    #     p = psutil.Process(0)
++    #     wmic_create = str(w.CreationDate.split('.')[0])
++    #     psutil_create = time.strftime("%Y%m%d%H%M%S",
++    #                                   time.localtime(p.create_time()))
++    #
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_pids(self):
++        # Note: this test might fail if the OS is starting/killing
++        # other processes in the meantime
++        w = wmi.WMI().Win32_Process()
++        wmi_pids = [x.ProcessId for x in w]
++        wmi_pids.sort()
++        psutil_pids = psutil.pids()
++        psutil_pids.sort()
++        if wmi_pids != psutil_pids:
++            difference = \
++                filter(lambda x: x not in wmi_pids, psutil_pids) + \
++                filter(lambda x: x not in psutil_pids, wmi_pids)
++            self.fail("difference: " + str(difference))
++
++    @unittest.skipIf(wmi is None, "wmi module is not installed")
++    def test_disks(self):
++        ps_parts = psutil.disk_partitions(all=True)
++        wmi_parts = wmi.WMI().Win32_LogicalDisk()
++        for ps_part in ps_parts:
++            for wmi_part in wmi_parts:
++                if ps_part.device.replace('\\', '') == wmi_part.DeviceID:
++                    if not ps_part.mountpoint:
++                        # this is usually a CD-ROM with no disk inserted
++                        break
+                     try:
+-                        call(p, name)
+-                        num1 = p.get_num_handles()
+-                        call(p, name)
+-                        num2 = p.get_num_handles()
+-                    except (psutil.NoSuchProcess, psutil.AccessDenied):
+-                        pass
+-                    else:
+-                        if num2 > num1:
+-                            fail = "failure while processing Process.%s method " \
+-                                   "(before=%s, after=%s)" % (name, num1, num2)
+-                            failures.append(fail)
+-            if failures:
+-                self.fail('\n' + '\n'.join(failures))
++                        usage = psutil.disk_usage(ps_part.mountpoint)
++                    except OSError as err:
++                        if err.errno == errno.ENOENT:
++                            # usually this is the floppy
++                            break
++                        else:
++                            raise
++                    self.assertEqual(usage.total, int(wmi_part.Size))
++                    wmi_free = int(wmi_part.FreeSpace)
++                    self.assertEqual(usage.free, wmi_free)
++                    # 10 MB tollerance
++                    if abs(usage.free - wmi_free) > 10 * 1024 * 1024:
++                        self.fail("psutil=%s, wmi=%s" % (
++                            usage.free, wmi_free))
++                    break
++            else:
++                self.fail("can't find partition %s" % repr(ps_part))
+ 
++    @unittest.skipIf(win32api is None, "pywin32 module is not installed")
++    def test_num_handles(self):
++        p = psutil.Process(os.getpid())
++        before = p.num_handles()
++        handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
++                                      win32con.FALSE, os.getpid())
++        after = p.num_handles()
++        self.assertEqual(after, before + 1)
++        win32api.CloseHandle(handle)
++        self.assertEqual(p.num_handles(), before)
++
++    @unittest.skipIf(win32api is None, "pywin32 module is not installed")
++    def test_num_handles_2(self):
++        # Note: this fails from time to time; I'm keen on thinking
++        # it doesn't mean something is broken
++        def call(p, attr):
++            attr = getattr(p, name, None)
++            if attr is not None and callable(attr):
++                attr()
++            else:
++                attr
+ 
+-import _psutil_mswindows
+-from psutil._psmswindows import ACCESS_DENIED_SET
++        p = psutil.Process(self.pid)
++        failures = []
++        for name in dir(psutil.Process):
++            if name.startswith('_') \
++                or name in ('terminate', 'kill', 'suspend', 'resume',
++                            'nice', 'send_signal', 'wait', 'children',
++                            'as_dict'):
++                continue
++            else:
++                try:
++                    call(p, name)
++                    num1 = p.num_handles()
++                    call(p, name)
++                    num2 = p.num_handles()
++                except (psutil.NoSuchProcess, psutil.AccessDenied):
++                    pass
++                else:
++                    if num2 > num1:
++                        fail = \
++                            "failure while processing Process.%s method " \
++                            "(before=%s, after=%s)" % (name, num1, num2)
++                        failures.append(fail)
++        if failures:
++            self.fail('\n' + '\n'.join(failures))
+ 
+-def wrap_exceptions(callable):
+-    def wrapper(self, *args, **kwargs):
+-        try:
+-            return callable(self, *args, **kwargs)
+-        except OSError:
+-            err = sys.exc_info()[1]
+-            if err.errno in ACCESS_DENIED_SET:
+-                raise psutil.AccessDenied(None, None)
+-            if err.errno == errno.ESRCH:
+-                raise psutil.NoSuchProcess(None, None)
+-            raise
+-    return wrapper
+ 
[email protected](WINDOWS, "not a Windows system")
+ class TestDualProcessImplementation(unittest.TestCase):
+     fun_names = [
+-        # function name                 tolerance
+-        ('get_process_cpu_times',       0.2),
+-        ('get_process_create_time',     0.5),
+-        ('get_process_num_handles',     1),  # 1 because impl #1 opens a handle
+-        ('get_process_io_counters',     0),
+-        ('get_process_memory_info',     1024),  # KB
++        # function name, tolerance
++        ('proc_cpu_times', 0.2),
++        ('proc_create_time', 0.5),
++        ('proc_num_handles', 1),  # 1 because impl #1 opens a handle
++        ('proc_memory_info', 1024),  # KB
++        ('proc_io_counters', 0),
+     ]
+ 
+     def test_compare_values(self):
+@@ -290,13 +302,13 @@
+         # case the first fails because of limited permission error.
+         # Here we test that the two methods return the exact same value,
+         # see:
+-        # http://code.google.com/p/psutil/issues/detail?id=304
++        # https://github.com/giampaolo/psutil/issues/304
+         def assert_ge_0(obj):
+             if isinstance(obj, tuple):
+                 for value in obj:
+-                    assert value >= 0, value
++                    self.assertGreaterEqual(value, 0, msg=obj)
+             elif isinstance(obj, (int, long, float)):
+-                assert obj >= 0, obj
++                self.assertGreaterEqual(obj, 0)
+             else:
+                 assert 0  # case not handled which needs to be fixed
+ 
+@@ -306,61 +318,88 @@
+             else:
+                 if isinstance(ret2, (int, long, float)):
+                     diff = abs(ret1 - ret2)
+-                    assert diff <= tolerance, diff
++                    self.assertLessEqual(diff, tolerance)
+                 elif isinstance(ret2, tuple):
+                     for a, b in zip(ret1, ret2):
+                         diff = abs(a - b)
+-                        assert diff <= tolerance, diff
++                        self.assertLessEqual(diff, tolerance)
+ 
++        from psutil._pswindows import ntpinfo
+         failures = []
+-        for name, tolerance in self.fun_names:
+-            meth1 = wrap_exceptions(getattr(_psutil_mswindows, name))
+-            meth2 = wrap_exceptions(getattr(_psutil_mswindows, name + '_2'))
+-            for p in psutil.process_iter():
+-                #
+-                try:
+-                    ret1 = meth1(p.pid)
+-                except psutil.NoSuchProcess:
++        for p in psutil.process_iter():
++            try:
++                nt = ntpinfo(*cext.proc_info(p.pid))
++            except psutil.NoSuchProcess:
++                continue
++            assert_ge_0(nt)
++
++            for name, tolerance in self.fun_names:
++                if name == 'proc_memory_info' and p.pid == os.getpid():
++                    continue
++                if name == 'proc_create_time' and p.pid in (0, 4):
+                     continue
+-                except psutil.AccessDenied:
+-                    ret1 = None
+-                #
++                meth = wrap_exceptions(getattr(cext, name))
+                 try:
+-                    ret2 = meth2(p.pid)
+-                except psutil.NoSuchProcess:
+-                    # this is supposed to fail only in case of zombie process
+-                    # never for permission error
++                    ret = meth(p.pid)
++                except (psutil.NoSuchProcess, psutil.AccessDenied):
+                     continue
+-
+                 # compare values
+                 try:
+-                    if ret1 is None:
+-                        assert_ge_0(ret2)
+-                    else:
+-                        compare_with_tolerance(ret1, ret2, tolerance)
+-                        assert_ge_0(ret1)
+-                        assert_ge_0(ret2)
++                    if name == 'proc_cpu_times':
++                        compare_with_tolerance(ret[0], nt.user_time, tolerance)
++                        compare_with_tolerance(ret[1],
++                                               nt.kernel_time, tolerance)
++                    elif name == 'proc_create_time':
++                        compare_with_tolerance(ret, nt.create_time, tolerance)
++                    elif name == 'proc_num_handles':
++                        compare_with_tolerance(ret, nt.num_handles, tolerance)
++                    elif name == 'proc_io_counters':
++                        compare_with_tolerance(ret[0], nt.io_rcount, tolerance)
++                        compare_with_tolerance(ret[1], nt.io_wcount, tolerance)
++                        compare_with_tolerance(ret[2], nt.io_rbytes, tolerance)
++                        compare_with_tolerance(ret[3], nt.io_wbytes, tolerance)
++                    elif name == 'proc_memory_info':
++                        try:
++                            rawtupl = cext.proc_memory_info_2(p.pid)
++                        except psutil.NoSuchProcess:
++                            continue
++                        compare_with_tolerance(ret, rawtupl, tolerance)
+                 except AssertionError:
+-                    err = sys.exc_info()[1]
+                     trace = traceback.format_exc()
+-                    msg = '%s\npid=%s, method=%r, ret_1=%r, ret_2=%r' \
+-                           % (trace, p.pid, name, ret1, ret2)
++                    msg = '%s\npid=%s, method=%r, ret_1=%r, ret_2=%r' % (
++                        trace, p.pid, name, ret, nt)
+                     failures.append(msg)
+                     break
++
+         if failures:
+             self.fail('\n\n'.join(failures))
+ 
++    def test_compare_name_exe(self):
++        for p in psutil.process_iter():
++            try:
++                a = os.path.basename(p.exe())
++                b = p.name()
++            except (psutil.NoSuchProcess, psutil.AccessDenied):
++                pass
++            else:
++                self.assertEqual(a, b)
++
+     def test_zombies(self):
+         # test that NPS is raised by the 2nd implementation in case a
+         # process no longer exists
+-        ZOMBIE_PID = max(psutil.get_pid_list()) + 5000
++        ZOMBIE_PID = max(psutil.pids()) + 5000
+         for name, _ in self.fun_names:
+-            meth = wrap_exceptions(getattr(_psutil_mswindows, name))
++            meth = wrap_exceptions(getattr(cext, name))
+             self.assertRaises(psutil.NoSuchProcess, meth, ZOMBIE_PID)
+ 
+ 
+-if __name__ == '__main__':
++def main():
+     test_suite = unittest.TestSuite()
+     test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase))
+     test_suite.addTest(unittest.makeSuite(TestDualProcessImplementation))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
++
++if __name__ == '__main__':
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/README.rst	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/test/README.rst	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,21 @@
++- The recommended way to run tests (also on Windows) is to cd into parent
++  directory and run ``make test``
++
++- Dependencies for running tests:
++   -  python 2.6: ipaddress, mock, unittest2
++   -  python 2.7: ipaddress, mock
++   -  python 3.2: ipaddress, mock
++   -  python 3.3: ipaddress
++   -  python >= 3.4: no deps required
++
++- The main test script is ``test_psutil.py``, which also imports platform-specific
++  ``_*.py`` scripts (which should be ignored).
++
++- ``test_memory_leaks.py`` looks for memory leaks into C extension modules and must
++  be run separately with ``make test-memleaks``.
++
++- To run tests on all supported Python version install tox (pip install tox)
++  then run ``tox``.
++
++- Every time a commit is pushed tests are automatically run on Travis:
++  https://travis-ci.org/giampaolo/psutil/
+--- mozjs-24.2.0/js/src/python/psutil/test/test_memory_leaks.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/test_memory_leaks.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,6 +1,6 @@
+ #!/usr/bin/env python
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+@@ -10,31 +10,40 @@
+ after the calls.  It might produce false positives.
+ """
+ 
+-import os
+ import gc
+-import unittest
+-import time
++import os
+ import socket
++import sys
+ import threading
+-import types
++import time
+ 
+ import psutil
+ import psutil._common
+-from psutil._compat import PY3, callable, xrange
+-from test_psutil import POSIX, LINUX, WINDOWS, OSX, BSD, TESTFN
+-from test_psutil import (reap_children, skipUnless, skipIf, supports_ipv6,
+-                         safe_remove, get_test_subprocess)
+ 
+-# disable cache for Process class properties
+-psutil._common.cached_property.enabled = False
++from psutil._compat import xrange
++from test_psutil import (WINDOWS, POSIX, OSX, LINUX, SUNOS, BSD, TESTFN,
++                         RLIMIT_SUPPORT, TRAVIS)
++from test_psutil import (reap_children, supports_ipv6, safe_remove,
++                         get_test_subprocess)
++
++if sys.version_info < (2, 7):
++    import unittest2 as unittest  # https://pypi.python.org/pypi/unittest2
++else:
++    import unittest
++
+ 
+ LOOPS = 1000
+ TOLERANCE = 4096
++SKIP_PYTHON_IMPL = True
+ 
+ 
+-class Base(unittest.TestCase):
++def skip_if_linux():
++    return unittest.skipIf(LINUX and SKIP_PYTHON_IMPL,
++                           "not worth being tested on LINUX (pure python)")
++
+ 
+-    proc = psutil.Process(os.getpid())
++class Base(unittest.TestCase):
++    proc = psutil.Process()
+ 
+     def execute(self, function, *args, **kwargs):
+         def call_many_times():
+@@ -64,7 +73,7 @@
+             # Let's keep calling fun for 3 more seconds and fail if
+             # we notice any difference.
+             stop_at = time.time() + 3
+-            while 1:
++            while True:
+                 self.call(function, *args, **kwargs)
+                 if time.time() >= stop_at:
+                     break
+@@ -73,11 +82,15 @@
+             rss3 = self.get_mem()
+             difference = rss3 - rss2
+             if rss3 > rss2:
+-                self.fail("rss2=%s, rss3=%s, difference=%s" \
++                self.fail("rss2=%s, rss3=%s, difference=%s"
+                           % (rss2, rss3, difference))
+ 
++    def execute_w_exc(self, exc, function, *args, **kwargs):
++        kwargs['_exc'] = exc
++        self.execute(function, *args, **kwargs)
++
+     def get_mem(self):
+-        return psutil.Process(os.getpid()).get_memory_info()[0]
++        return psutil.Process().memory_info()[0]
+ 
+     def call(self, *args, **kwargs):
+         raise NotImplementedError("must be implemented in subclass")
+@@ -86,18 +99,6 @@
+ class TestProcessObjectLeaks(Base):
+     """Test leaks of Process class methods and properties"""
+ 
+-    def __init__(self, *args, **kwargs):
+-        Base.__init__(self, *args, **kwargs)
+-        # skip tests which are not supported by Process API
+-        supported_attrs = dir(psutil.Process)
+-        for attr in [x for x in dir(self) if x.startswith('test')]:
+-            if attr[5:] not in supported_attrs:
+-                meth = getattr(self, attr)
+-                @skipIf(True)
+-                def test_(self):
+-                    pass
+-                setattr(self, attr, types.MethodType(test_, self))
+-
+     def setUp(self):
+         gc.collect()
+ 
+@@ -105,114 +106,167 @@
+         reap_children()
+ 
+     def call(self, function, *args, **kwargs):
+-        try:
+-            obj = getattr(self.proc, function)
+-            if callable(obj):
+-                obj(*args, **kwargs)
+-        except psutil.Error:
+-            pass
++        meth = getattr(self.proc, function)
++        if '_exc' in kwargs:
++            exc = kwargs.pop('_exc')
++            self.assertRaises(exc, meth, *args, **kwargs)
++        else:
++            try:
++                meth(*args, **kwargs)
++            except psutil.Error:
++                pass
+ 
++    @skip_if_linux()
+     def test_name(self):
+         self.execute('name')
+ 
++    @skip_if_linux()
+     def test_cmdline(self):
+         self.execute('cmdline')
+ 
++    @skip_if_linux()
+     def test_exe(self):
+         self.execute('exe')
+ 
++    @skip_if_linux()
+     def test_ppid(self):
+         self.execute('ppid')
+ 
++    @unittest.skipUnless(POSIX, "POSIX only")
++    @skip_if_linux()
+     def test_uids(self):
+         self.execute('uids')
+ 
++    @unittest.skipUnless(POSIX, "POSIX only")
++    @skip_if_linux()
+     def test_gids(self):
+         self.execute('gids')
+ 
++    @skip_if_linux()
+     def test_status(self):
+         self.execute('status')
+ 
+-    def test_get_nice(self):
+-        self.execute('get_nice')
+-
+-    def test_set_nice(self):
+-        niceness = psutil.Process(os.getpid()).get_nice()
+-        self.execute('set_nice', niceness)
+-
+-    def test_get_io_counters(self):
+-        self.execute('get_io_counters')
++    def test_nice_get(self):
++        self.execute('nice')
+ 
+-    def test_get_ionice(self):
+-        self.execute('get_ionice')
+-
+-    def test_set_ionice(self):
++    def test_nice_set(self):
++        niceness = psutil.Process().nice()
++        self.execute('nice', niceness)
++
++    @unittest.skipUnless(hasattr(psutil.Process, 'ionice'),
++                         "Linux and Windows Vista only")
++    def test_ionice_get(self):
++        self.execute('ionice')
++
++    @unittest.skipUnless(hasattr(psutil.Process, 'ionice'),
++                         "Linux and Windows Vista only")
++    def test_ionice_set(self):
+         if WINDOWS:
+-            value = psutil.Process(os.getpid()).get_ionice()
+-            self.execute('set_ionice', value)
++            value = psutil.Process().ionice()
++            self.execute('ionice', value)
+         else:
+-            self.execute('set_ionice', psutil.IOPRIO_CLASS_NONE)
++            self.execute('ionice', psutil.IOPRIO_CLASS_NONE)
++            self.execute_w_exc(OSError, 'ionice', -1)
++
++    @unittest.skipIf(OSX or SUNOS, "feature not supported on this platform")
++    @skip_if_linux()
++    def test_io_counters(self):
++        self.execute('io_counters')
+ 
++    @unittest.skipUnless(WINDOWS, "not worth being tested on posix")
+     def test_username(self):
+         self.execute('username')
+ 
++    @skip_if_linux()
+     def test_create_time(self):
+         self.execute('create_time')
+ 
+-    def test_get_num_threads(self):
+-        self.execute('get_num_threads')
+-
+-    def test_get_num_handles(self):
+-        self.execute('get_num_handles')
+-
+-    def test_get_num_fds(self):
+-        self.execute('get_num_fds')
++    @skip_if_linux()
++    def test_num_threads(self):
++        self.execute('num_threads')
++
++    @unittest.skipUnless(WINDOWS, "Windows only")
++    def test_num_handles(self):
++        self.execute('num_handles')
++
++    @unittest.skipUnless(POSIX, "POSIX only")
++    @skip_if_linux()
++    def test_num_fds(self):
++        self.execute('num_fds')
++
++    @skip_if_linux()
++    def test_threads(self):
++        self.execute('threads')
+ 
+-    def test_get_threads(self):
+-        self.execute('get_threads')
+-
+-    def test_get_cpu_times(self):
+-        self.execute('get_cpu_times')
+-
+-    def test_get_memory_info(self):
+-        self.execute('get_memory_info')
++    @skip_if_linux()
++    def test_cpu_times(self):
++        self.execute('cpu_times')
+ 
+-    def test_get_ext_memory_info(self):
+-        self.execute('get_ext_memory_info')
++    @skip_if_linux()
++    def test_memory_info(self):
++        self.execute('memory_info')
++
++    @skip_if_linux()
++    def test_memory_info_ex(self):
++        self.execute('memory_info_ex')
+ 
++    @unittest.skipUnless(POSIX, "POSIX only")
++    @skip_if_linux()
+     def test_terminal(self):
+         self.execute('terminal')
+ 
+-    @skipUnless(WINDOWS)
++    @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
++                     "not worth being tested on POSIX (pure python)")
+     def test_resume(self):
+         self.execute('resume')
+ 
+-    def test_getcwd(self):
+-        self.execute('getcwd')
+-
+-    def test_get_cpu_affinity(self):
+-        self.execute('get_cpu_affinity')
++    @skip_if_linux()
++    def test_cwd(self):
++        self.execute('cwd')
++
++    @unittest.skipUnless(WINDOWS or LINUX or BSD,
++                         "Windows or Linux or BSD only")
++    def test_cpu_affinity_get(self):
++        self.execute('cpu_affinity')
++
++    @unittest.skipUnless(WINDOWS or LINUX or BSD,
++                         "Windows or Linux or BSD only")
++    def test_cpu_affinity_set(self):
++        affinity = psutil.Process().cpu_affinity()
++        self.execute('cpu_affinity', affinity)
++        if not TRAVIS:
++            self.execute_w_exc(ValueError, 'cpu_affinity', [-1])
+ 
+-    def test_set_cpu_affinity(self):
+-        affinity = psutil.Process(os.getpid()).get_cpu_affinity()
+-        self.execute('set_cpu_affinity', affinity)
+-
+-    def test_get_open_files(self):
++    @skip_if_linux()
++    def test_open_files(self):
+         safe_remove(TESTFN)  # needed after UNIX socket test has run
+-        f = open(TESTFN, 'w')
+-        try:
+-            self.execute('get_open_files')
+-        finally:
+-            f.close()
++        with open(TESTFN, 'w'):
++            self.execute('open_files')
+ 
+     # OSX implementation is unbelievably slow
+-    @skipIf(OSX)
+-    def test_get_memory_maps(self):
+-        self.execute('get_memory_maps')
+-
+-    # Linux implementation is pure python so since it's slow we skip it
+-    @skipIf(LINUX)
+-    def test_get_connections(self):
++    @unittest.skipIf(OSX, "OSX implementation is too slow")
++    @skip_if_linux()
++    def test_memory_maps(self):
++        self.execute('memory_maps')
++
++    @unittest.skipUnless(LINUX, "Linux only")
++    @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
++                         "only available on Linux >= 2.6.36")
++    def test_rlimit_get(self):
++        self.execute('rlimit', psutil.RLIMIT_NOFILE)
++
++    @unittest.skipUnless(LINUX, "Linux only")
++    @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
++                         "only available on Linux >= 2.6.36")
++    def test_rlimit_set(self):
++        limit = psutil.Process().rlimit(psutil.RLIMIT_NOFILE)
++        self.execute('rlimit', psutil.RLIMIT_NOFILE, limit)
++        self.execute_w_exc(OSError, 'rlimit', -1)
++
++    @skip_if_linux()
++    # Windows implementation is based on a single system-wide function
++    @unittest.skipIf(WINDOWS, "tested later")
++    def test_connections(self):
+         def create_socket(family, type):
+             sock = socket.socket(family, type)
+             sock.bind(('', 0))
+@@ -232,8 +286,14 @@
+             s.bind(TESTFN)
+             s.listen(1)
+             socks.append(s)
++        kind = 'all'
++        # TODO: UNIX sockets are temporarily implemented by parsing
++        # 'pfiles' cmd  output; we don't want that part of the code to
++        # be executed.
++        if SUNOS:
++            kind = 'inet'
+         try:
+-            self.execute('get_connections', kind='all')
++            self.execute('connections', kind=kind)
+         finally:
+             for s in socks:
+                 s.close()
+@@ -245,12 +305,19 @@
+ DEAD_PROC.wait()
+ del p
+ 
++
+ class TestProcessObjectLeaksZombie(TestProcessObjectLeaks):
+     """Same as above but looks for leaks occurring when dealing with
+     zombie processes raising NoSuchProcess exception.
+     """
+     proc = DEAD_PROC
+ 
++    def call(self, *args, **kwargs):
++        try:
++            TestProcessObjectLeaks.call(self, *args, **kwargs)
++        except psutil.NoSuchProcess:
++            pass
++
+     if not POSIX:
+         def test_kill(self):
+             self.execute('kill')
+@@ -275,53 +342,91 @@
+         gc.collect()
+ 
+     def call(self, function, *args, **kwargs):
+-        obj = getattr(psutil, function)
+-        if callable(obj):
+-            retvalue = obj(*args, **kwargs)
++        fun = getattr(psutil, function)
++        fun(*args, **kwargs)
++
++    @skip_if_linux()
++    def test_cpu_count_logical(self):
++        psutil.cpu_count = psutil._psplatform.cpu_count_logical
++        self.execute('cpu_count')
++
++    @skip_if_linux()
++    def test_cpu_count_physical(self):
++        psutil.cpu_count = psutil._psplatform.cpu_count_physical
++        self.execute('cpu_count')
++
++    @skip_if_linux()
++    def test_boot_time(self):
++        self.execute('boot_time')
+ 
+-    @skipIf(POSIX)
++    @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
++                     "not worth being tested on POSIX (pure python)")
+     def test_pid_exists(self):
+         self.execute('pid_exists', os.getpid())
+ 
+     def test_virtual_memory(self):
+         self.execute('virtual_memory')
+ 
++    # TODO: remove this skip when this gets fixed
++    @unittest.skipIf(SUNOS,
++                     "not worth being tested on SUNOS (uses a subprocess)")
+     def test_swap_memory(self):
+         self.execute('swap_memory')
+ 
++    @skip_if_linux()
+     def test_cpu_times(self):
+         self.execute('cpu_times')
+ 
++    @skip_if_linux()
+     def test_per_cpu_times(self):
+         self.execute('cpu_times', percpu=True)
+ 
+-    @skipUnless(WINDOWS)
++    @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
++                     "not worth being tested on POSIX (pure python)")
+     def test_disk_usage(self):
+         self.execute('disk_usage', '.')
+ 
+     def test_disk_partitions(self):
+         self.execute('disk_partitions')
+ 
+-    def test_network_io_counters(self):
+-        self.execute('network_io_counters')
+-
++    @skip_if_linux()
++    def test_net_io_counters(self):
++        self.execute('net_io_counters')
++
++    @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
++                     '/proc/diskstats not available on this Linux version')
++    @skip_if_linux()
+     def test_disk_io_counters(self):
+         self.execute('disk_io_counters')
+ 
+     # XXX - on Windows this produces a false positive
+-    @skipIf(WINDOWS)
+-    def test_get_users(self):
+-        self.execute('get_users')
++    @unittest.skipIf(WINDOWS, "XXX produces a false positive on Windows")
++    def test_users(self):
++        self.execute('users')
++
++    @unittest.skipIf(LINUX,
++                     "not worth being tested on Linux (pure python)")
++    def test_net_connections(self):
++        self.execute('net_connections')
++
++    def test_net_if_addrs(self):
++        self.execute('net_if_addrs')
++
++    @unittest.skipIf(TRAVIS, "EPERM on travis")
++    def test_net_if_stats(self):
++        self.execute('net_if_stats')
+ 
+ 
+-def test_main():
++def main():
+     test_suite = unittest.TestSuite()
+     tests = [TestProcessObjectLeaksZombie,
+              TestProcessObjectLeaks,
+-             TestModuleFunctionsLeaks,]
++             TestModuleFunctionsLeaks]
+     for test in tests:
+         test_suite.addTest(unittest.makeSuite(test))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
+ 
+ if __name__ == '__main__':
+-    test_main()
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/test/test_psutil.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/psutil/test/test_psutil.py	2015-06-17 19:33:33.000000000 -0700
+@@ -1,53 +1,132 @@
+ #!/usr/bin/env python
++# -*- coding: utf-8 -*-
+ 
+-# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
++# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ # Use of this source code is governed by a BSD-style license that can be
+ # found in the LICENSE file.
+ 
+ """
+-psutil test suite.
++psutil test suite. Run it with:
++$ make test
+ 
+-Note: this is targeted for both python 2.x and 3.x so there's no need
+-to use 2to3 tool first.
++If you're on Python < 2.7 unittest2 module must be installed first:
++https://pypi.python.org/pypi/unittest2
+ """
+ 
+ from __future__ import division
+-import unittest
++
++import ast
++import atexit
++import collections
++import contextlib
++import datetime
++import errno
++import functools
++import imp
++import json
+ import os
+-import sys
++import pickle
++import re
++import select
++import shutil
++import signal
++import socket
++import stat
+ import subprocess
++import sys
++import tempfile
++import textwrap
++import threading
+ import time
+-import signal
+-import types
+ import traceback
+-import socket
++import types
+ import warnings
+-import atexit
+-import errno
+-import threading
+-import tempfile
+-import stat
+-import collections
+-import datetime
++from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
++try:
++    import ipaddress  # python >= 3.3
++except ImportError:
++    ipaddress = None
+ 
+ import psutil
+-from psutil._compat import PY3, callable, long, wraps
++from psutil._compat import PY3, callable, long, unicode
+ 
++if sys.version_info < (2, 7):
++    import unittest2 as unittest  # https://pypi.python.org/pypi/unittest2
++else:
++    import unittest
++if sys.version_info >= (3, 4):
++    import enum
++else:
++    enum = None
++
++
++# ===================================================================
++# --- Constants
++# ===================================================================
++
++# conf for retry_before_failing() decorator
++NO_RETRIES = 10
++# bytes tolerance for OS memory related tests
++TOLERANCE = 500 * 1024  # 500KB
++# the timeout used in functions which have to wait
++GLOBAL_TIMEOUT = 3
+ 
++AF_INET6 = getattr(socket, "AF_INET6")
++AF_UNIX = getattr(socket, "AF_UNIX", None)
+ PYTHON = os.path.realpath(sys.executable)
+ DEVNULL = open(os.devnull, 'r+')
+ TESTFN = os.path.join(os.getcwd(), "$testfile")
++TESTFN_UNICODE = TESTFN + "ƒőő"
++TESTFILE_PREFIX = 'psutil-test-suite-'
++if not PY3:
++    try:
++        TESTFN_UNICODE = unicode(TESTFN_UNICODE, sys.getfilesystemencoding())
++    except UnicodeDecodeError:
++        TESTFN_UNICODE = TESTFN + "???"
++
++EXAMPLES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
++                               '..', 'examples'))
++
+ POSIX = os.name == 'posix'
++WINDOWS = os.name == 'nt'
++if WINDOWS:
++    WIN_VISTA = (6, 0, 0)
+ LINUX = sys.platform.startswith("linux")
+-WINDOWS = sys.platform.startswith("win32")
+ OSX = sys.platform.startswith("darwin")
+ BSD = sys.platform.startswith("freebsd")
++SUNOS = sys.platform.startswith("sunos")
++VALID_PROC_STATUSES = [getattr(psutil, x) for x in dir(psutil)
++                       if x.startswith('STATUS_')]
++# whether we're running this test suite on Travis (https://travis-ci.org/)
++TRAVIS = bool(os.environ.get('TRAVIS'))
++
++if TRAVIS or 'tox' in sys.argv[0]:
++    import ipaddress
++
++
++# ===================================================================
++# --- Utility functions
++# ===================================================================
++
++def cleanup():
++    reap_children(search_all=True)
++    safe_remove(TESTFN)
++    try:
++        safe_rmdir(TESTFN_UNICODE)
++    except UnicodeEncodeError:
++        pass
++    for path in _testfiles:
++        safe_remove(path)
++
++atexit.register(cleanup)
++atexit.register(lambda: DEVNULL.close())
+ 
+ 
+ _subprocesses_started = set()
+ 
+-def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL, stdin=DEVNULL,
+-                        wait=False):
++
++def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL,
++                        stdin=DEVNULL, wait=False):
+     """Return a subprocess.Popen object to use in tests.
+     By default stdout and stderr are redirected to /dev/null and the
+     python interpreter is used as test process.
+@@ -58,7 +137,7 @@
+         pyline = ""
+         if wait:
+             pyline += "open(r'%s', 'w'); " % TESTFN
+-        pyline += "import time; time.sleep(3600);"
++        pyline += "import time; time.sleep(60);"
+         cmd_ = [PYTHON, "-c", pyline]
+     else:
+         cmd_ = cmd
+@@ -74,12 +153,34 @@
+                 warn("couldn't make sure test file was actually created")
+         else:
+             wait_for_pid(sproc.pid)
+-    _subprocesses_started.add(sproc.pid)
++    _subprocesses_started.add(psutil.Process(sproc.pid))
+     return sproc
+ 
+-def warn(msg, warntype=RuntimeWarning):
++
++_testfiles = []
++
++
++def pyrun(src):
++    """Run python code 'src' in a separate interpreter.
++    Return interpreter subprocess.
++    """
++    if PY3:
++        src = bytes(src, 'ascii')
++    with tempfile.NamedTemporaryFile(
++            prefix=TESTFILE_PREFIX, delete=False) as f:
++        _testfiles.append(f.name)
++        f.write(src)
++        f.flush()
++        subp = get_test_subprocess([PYTHON, f.name], stdout=None,
++                                   stderr=None)
++        wait_for_pid(subp.pid)
++        return subp
++
++
++def warn(msg):
+     """Raise a warning msg."""
+-    warnings.warn(msg, warntype)
++    warnings.warn(msg, UserWarning)
++
+ 
+ def sh(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
+     """run cmd in a subprocess and return its output.
+@@ -95,6 +196,7 @@
+         stdout = str(stdout, sys.stdout.encoding)
+     return stdout.strip()
+ 
++
+ def which(program):
+     """Same as UNIX which command. Return None on command not found."""
+     def is_exe(fpath):
+@@ -111,13 +213,43 @@
+                 return exe_file
+     return None
+ 
+-def wait_for_pid(pid, timeout=1):
++
++if POSIX:
++    def get_kernel_version():
++        """Return a tuple such as (2, 6, 36)."""
++        s = ""
++        uname = os.uname()[2]
++        for c in uname:
++            if c.isdigit() or c == '.':
++                s += c
++            else:
++                break
++        if not s:
++            raise ValueError("can't parse %r" % uname)
++        minor = 0
++        micro = 0
++        nums = s.split('.')
++        major = int(nums[0])
++        if len(nums) >= 2:
++            minor = int(nums[1])
++        if len(nums) >= 3:
++            micro = int(nums[2])
++        return (major, minor, micro)
++
++
++if LINUX:
++    RLIMIT_SUPPORT = get_kernel_version() >= (2, 6, 36)
++else:
++    RLIMIT_SUPPORT = False
++
++
++def wait_for_pid(pid, timeout=GLOBAL_TIMEOUT):
+     """Wait for pid to show up in the process list then return.
+     Used in the test suite to give time the sub process to initialize.
+     """
+     raise_at = time.time() + timeout
+-    while 1:
+-        if pid in psutil.get_pid_list():
++    while True:
++        if pid in psutil.pids():
+             # give it one more iteration to allow full initialization
+             time.sleep(0.01)
+             return
+@@ -125,50 +257,160 @@
+         if time.time() >= raise_at:
+             raise RuntimeError("Timed out")
+ 
++
++def wait_for_file(fname, timeout=GLOBAL_TIMEOUT, delete_file=True):
++    """Wait for a file to be written on disk."""
++    stop_at = time.time() + 3
++    while time.time() < stop_at:
++        try:
++            with open(fname, "r") as f:
++                data = f.read()
++            if not data:
++                continue
++            if delete_file:
++                os.remove(fname)
++            return data
++        except IOError:
++            time.sleep(0.001)
++    raise RuntimeError("timed out (couldn't read file)")
++
++
+ def reap_children(search_all=False):
+     """Kill any subprocess started by this test suite and ensure that
+     no zombies stick around to hog resources and create problems when
+     looking for refleaks.
+     """
+-    pids = _subprocesses_started
++    global _subprocesses_started
++    procs = _subprocesses_started.copy()
+     if search_all:
+-        this_process = psutil.Process(os.getpid())
+-        for p in this_process.get_children(recursive=True):
+-            pids.add(p.pid)
+-    while pids:
+-        pid = pids.pop()
++        this_process = psutil.Process()
++        for p in this_process.children(recursive=True):
++            procs.add(p)
++    for p in procs:
+         try:
+-            child = psutil.Process(pid)
+-            child.kill()
++            p.terminate()
+         except psutil.NoSuchProcess:
+             pass
+-        except psutil.AccessDenied:
+-            warn("couldn't kill child process with pid %s" % pid)
+-        else:
+-            child.wait(timeout=3)
++    gone, alive = psutil.wait_procs(procs, timeout=GLOBAL_TIMEOUT)
++    for p in alive:
++        warn("couldn't terminate process %s" % p)
++        try:
++            p.kill()
++        except psutil.NoSuchProcess:
++            pass
++    _, alive = psutil.wait_procs(alive, timeout=GLOBAL_TIMEOUT)
++    if alive:
++        warn("couldn't not kill processes %s" % str(alive))
++    _subprocesses_started = set(alive)
++
+ 
+ def check_ip_address(addr, family):
+     """Attempts to check IP address's validity."""
+-    if not addr:
+-        return
+-    ip, port = addr
+-    assert isinstance(port, int), port
+-    if family == socket.AF_INET:
+-        ip = list(map(int, ip.split('.')))
+-        assert len(ip) == 4, ip
+-        for num in ip:
+-            assert 0 <= num <= 255, ip
+-    assert 0 <= port <= 65535, port
++    if enum and PY3:
++        assert isinstance(family, enum.IntEnum), family
++    if family == AF_INET:
++        octs = [int(x) for x in addr.split('.')]
++        assert len(octs) == 4, addr
++        for num in octs:
++            assert 0 <= num <= 255, addr
++        if ipaddress:
++            if not PY3:
++                addr = unicode(addr)
++            ipaddress.IPv4Address(addr)
++    elif family == AF_INET6:
++        assert isinstance(addr, str), addr
++        if ipaddress:
++            if not PY3:
++                addr = unicode(addr)
++            ipaddress.IPv6Address(addr)
++    elif family == psutil.AF_LINK:
++        assert re.match('([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
++    else:
++        raise ValueError("unknown family %r", family)
++
+ 
+-def safe_remove(fname):
++def check_connection_ntuple(conn):
++    """Check validity of a connection namedtuple."""
++    valid_conn_states = [getattr(psutil, x) for x in dir(psutil) if
++                         x.startswith('CONN_')]
++    assert conn[0] == conn.fd
++    assert conn[1] == conn.family
++    assert conn[2] == conn.type
++    assert conn[3] == conn.laddr
++    assert conn[4] == conn.raddr
++    assert conn[5] == conn.status
++    assert conn.type in (SOCK_STREAM, SOCK_DGRAM), repr(conn.type)
++    assert conn.family in (AF_INET, AF_INET6, AF_UNIX), repr(conn.family)
++    assert conn.status in valid_conn_states, conn.status
++
++    # check IP address and port sanity
++    for addr in (conn.laddr, conn.raddr):
++        if not addr:
++            continue
++        if conn.family in (AF_INET, AF_INET6):
++            assert isinstance(addr, tuple), addr
++            ip, port = addr
++            assert isinstance(port, int), port
++            assert 0 <= port <= 65535, port
++            check_ip_address(ip, conn.family)
++        elif conn.family == AF_UNIX:
++            assert isinstance(addr, (str, None)), addr
++        else:
++            raise ValueError("unknown family %r", conn.family)
++
++    if conn.family in (AF_INET, AF_INET6):
++        # actually try to bind the local socket; ignore IPv6
++        # sockets as their address might be represented as
++        # an IPv4-mapped-address (e.g. "::127.0.0.1")
++        # and that's rejected by bind()
++        if conn.family == AF_INET:
++            s = socket.socket(conn.family, conn.type)
++            with contextlib.closing(s):
++                try:
++                    s.bind((conn.laddr[0], 0))
++                except socket.error as err:
++                    if err.errno != errno.EADDRNOTAVAIL:
++                        raise
++    elif conn.family == AF_UNIX:
++        assert not conn.raddr, repr(conn.raddr)
++        assert conn.status == psutil.CONN_NONE, conn.status
++
++    if getattr(conn, 'fd', -1) != -1:
++        assert conn.fd > 0, conn
++        if hasattr(socket, 'fromfd') and not WINDOWS:
++            try:
++                dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
++            except (socket.error, OSError) as err:
++                if err.args[0] != errno.EBADF:
++                    raise
++            else:
++                with contextlib.closing(dupsock):
++                    assert dupsock.family == conn.family
++                    assert dupsock.type == conn.type
++
++
++def safe_remove(file):
++    "Convenience function for removing temporary test files"
+     try:
+-        os.remove(fname)
+-    except OSError:
+-        err = sys.exc_info()[1]
+-        if err.args[0] != errno.ENOENT:
++        os.remove(file)
++    except OSError as err:
++        if err.errno != errno.ENOENT:
++            # file is being used by another process
++            if WINDOWS and isinstance(err, WindowsError) and err.errno == 13:
++                return
+             raise
+ 
+-def call_until(fun, expr, timeout=1):
++
++def safe_rmdir(dir):
++    "Convenience function for removing temporary test directories"
++    try:
++        os.rmdir(dir)
++    except OSError as err:
++        if err.errno != errno.ENOENT:
++            raise
++
++
++def call_until(fun, expr, timeout=GLOBAL_TIMEOUT):
+     """Keep calling function for timeout secs and exit if eval()
+     expression is True.
+     """
+@@ -181,42 +423,27 @@
+     raise RuntimeError('timed out (ret=%r)' % ret)
+ 
+ 
+-def skipIf(condition, reason="", warn=False):
+-    """Decorator which skip a test under if condition is satisfied.
+-    This is a substitute of unittest.skipIf which is available
+-    only in python 2.7 and 3.2.
+-    If 'reason' argument is provided this will be printed during
+-    tests execution.
+-    If 'warn' is provided a RuntimeWarning will be shown when all
+-    tests are run.
++def retry_before_failing(ntimes=None):
++    """Decorator which runs a test function and retries N times before
++    actually failing.
+     """
+-    def outer(fun, *args, **kwargs):
+-        def inner(self):
+-            if condition:
+-                sys.stdout.write("skipped-")
+-                sys.stdout.flush()
+-                if warn:
+-                    objname = "%s.%s" % (self.__class__.__name__, fun.__name__)
+-                    msg = "%s was skipped" % objname
+-                    if reason:
+-                        msg += "; reason: " + repr(reason)
+-                    atexit.register(warn, msg)
+-                return
+-            else:
+-                return fun(self, *args, **kwargs)
+-        return inner
+-    return outer
+-
+-def skipUnless(condition, reason="", warn=False):
+-    """Contrary of skipIf."""
+-    if not condition:
+-        return skipIf(True, reason, warn)
+-    return skipIf(False)
++    def decorator(fun):
++        @functools.wraps(fun)
++        def wrapper(*args, **kwargs):
++            for x in range(ntimes or NO_RETRIES):
++                try:
++                    return fun(*args, **kwargs)
++                except AssertionError:
++                    pass
++            raise
++        return wrapper
++    return decorator
++
+ 
+ def skip_on_access_denied(only_if=None):
+     """Decorator to Ignore AccessDenied exceptions."""
+     def decorator(fun):
+-        @wraps(fun)
++        @functools.wraps(fun)
+         def wrapper(*args, **kwargs):
+             try:
+                 return fun(*args, **kwargs)
+@@ -224,8 +451,27 @@
+                 if only_if is not None:
+                     if not only_if:
+                         raise
+-                atexit.register(warn, "%r was skipped because it raised " \
+-                                      "AccessDenied" % fun.__name__)
++                msg = "%r was skipped because it raised AccessDenied" \
++                      % fun.__name__
++                raise unittest.SkipTest(msg)
++        return wrapper
++    return decorator
++
++
++def skip_on_not_implemented(only_if=None):
++    """Decorator to Ignore NotImplementedError exceptions."""
++    def decorator(fun):
++        @functools.wraps(fun)
++        def wrapper(*args, **kwargs):
++            try:
++                return fun(*args, **kwargs)
++            except NotImplementedError:
++                if only_if is not None:
++                    if not only_if:
++                        raise
++                msg = "%r was skipped because it raised NotImplementedError" \
++                      % fun.__name__
++                raise unittest.SkipTest(msg)
+         return wrapper
+     return decorator
+ 
+@@ -236,18 +482,31 @@
+         return False
+     sock = None
+     try:
+-        try:
+-            sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+-            sock.bind(("::1", 0))
+-        except (socket.error, socket.gaierror):
+-            return False
+-        else:
+-            return True
++        sock = socket.socket(AF_INET6, SOCK_STREAM)
++        sock.bind(("::1", 0))
++    except (socket.error, socket.gaierror):
++        return False
++    else:
++        return True
+     finally:
+         if sock is not None:
+             sock.close()
+ 
+ 
++if WINDOWS:
++    def get_winver():
++        wv = sys.getwindowsversion()
++        if hasattr(wv, 'service_pack_major'):  # python >= 2.7
++            sp = wv.service_pack_major or 0
++        else:
++            r = re.search("\s\d$", wv[4])
++            if r:
++                sp = int(r.group(0))
++            else:
++                sp = 0
++        return (wv[0], wv[1], sp)
++
++
+ class ThreadTask(threading.Thread):
+     """A thread object used for running process thread tests."""
+ 
+@@ -258,7 +517,7 @@
+         self._flag = threading.Event()
+ 
+     def __repr__(self):
+-        name =  self.__class__.__name__
++        name = self.__class__.__name__
+         return '<%s running=%s at %#x>' % (name, self._running, id(self))
+ 
+     def start(self, interval=0.001):
+@@ -285,7 +544,12 @@
+         self.join()
+ 
+ 
+-class TestCase(unittest.TestCase):
++# ===================================================================
++# --- System-related API tests
++# ===================================================================
++
++class TestSystemAPIs(unittest.TestCase):
++    """Tests for system-related APIs."""
+ 
+     def setUp(self):
+         safe_remove(TESTFN)
+@@ -293,59 +557,77 @@
+     def tearDown(self):
+         reap_children()
+ 
+-    if not hasattr(unittest.TestCase, "assertIn"):
+-        def assertIn(self, member, container, msg=None):
+-            if member not in container:
+-                self.fail(msg or \
+-                        '%s not found in %s' % (repr(member), repr(container)))
+-
+-    def assert_eq_w_tol(self, first, second, tolerance):
+-        difference = abs(first - second)
+-        if difference <= tolerance:
+-            return
+-        msg = '%r != %r within %r delta (%r difference)' \
+-              % (first, second, tolerance, difference)
+-        raise AssertionError(msg)
+-
+-    # ============================
+-    # tests for system-related API
+-    # ============================
+-
+     def test_process_iter(self):
+-        assert os.getpid() in [x.pid for x in psutil.process_iter()]
++        self.assertIn(os.getpid(), [x.pid for x in psutil.process_iter()])
+         sproc = get_test_subprocess()
+-        assert sproc.pid in [x.pid for x in psutil.process_iter()]
++        self.assertIn(sproc.pid, [x.pid for x in psutil.process_iter()])
+         p = psutil.Process(sproc.pid)
+         p.kill()
+         p.wait()
+-        assert sproc.pid not in [x.pid for x in psutil.process_iter()]
++        self.assertNotIn(sproc.pid, [x.pid for x in psutil.process_iter()])
+ 
+-    def test_TOTAL_PHYMEM(self):
+-        x = psutil.TOTAL_PHYMEM
+-        assert isinstance(x, (int, long))
+-        assert x > 0
+-        self.assertEqual(x, psutil.virtual_memory().total)
+-
+-    def test_BOOT_TIME(self, arg=None):
+-        x = arg or psutil.BOOT_TIME
+-        assert isinstance(x, float), x
+-        assert x > 0, x
+-        assert x < time.time(), x
+-
+-    def test_get_boot_time(self):
+-        self.test_BOOT_TIME(psutil.get_boot_time())
+-        if WINDOWS:
+-            # work around float precision issues; give it 1 secs tolerance
+-            diff = abs(psutil.get_boot_time() - psutil.BOOT_TIME)
+-            assert diff < 1, diff
++    @retry_before_failing(50)
++    def test_process_iter_against_pids(self):
++        self.assertEqual(len(list(psutil.process_iter())), len(psutil.pids()))
++
++    def test_wait_procs(self):
++        def callback(p):
++            l.append(p.pid)
++
++        l = []
++        sproc1 = get_test_subprocess()
++        sproc2 = get_test_subprocess()
++        sproc3 = get_test_subprocess()
++        procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
++        self.assertRaises(ValueError, psutil.wait_procs, procs, timeout=-1)
++        t = time.time()
++        gone, alive = psutil.wait_procs(procs, timeout=0.01, callback=callback)
++
++        self.assertLess(time.time() - t, 0.5)
++        self.assertEqual(gone, [])
++        self.assertEqual(len(alive), 3)
++        self.assertEqual(l, [])
++        for p in alive:
++            self.assertFalse(hasattr(p, 'returncode'))
++
++        sproc3.terminate()
++        gone, alive = psutil.wait_procs(procs, timeout=0.03, callback=callback)
++        self.assertEqual(len(gone), 1)
++        self.assertEqual(len(alive), 2)
++        self.assertIn(sproc3.pid, [x.pid for x in gone])
++        if POSIX:
++            self.assertEqual(gone.pop().returncode, signal.SIGTERM)
+         else:
+-            self.assertEqual(psutil.get_boot_time(), psutil.BOOT_TIME)
+-
+-    def test_NUM_CPUS(self):
+-        self.assertEqual(psutil.NUM_CPUS, len(psutil.cpu_times(percpu=True)))
+-        assert psutil.NUM_CPUS >= 1, psutil.NUM_CPUS
++            self.assertEqual(gone.pop().returncode, 1)
++        self.assertEqual(l, [sproc3.pid])
++        for p in alive:
++            self.assertFalse(hasattr(p, 'returncode'))
++
++        sproc1.terminate()
++        sproc2.terminate()
++        gone, alive = psutil.wait_procs(procs, timeout=0.03, callback=callback)
++        self.assertEqual(len(gone), 3)
++        self.assertEqual(len(alive), 0)
++        self.assertEqual(set(l), set([sproc1.pid, sproc2.pid, sproc3.pid]))
++        for p in gone:
++            self.assertTrue(hasattr(p, 'returncode'))
++
++    def test_wait_procs_no_timeout(self):
++        sproc1 = get_test_subprocess()
++        sproc2 = get_test_subprocess()
++        sproc3 = get_test_subprocess()
++        procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
++        for p in procs:
++            p.terminate()
++        gone, alive = psutil.wait_procs(procs)
++
++    def test_boot_time(self):
++        bt = psutil.boot_time()
++        self.assertIsInstance(bt, float)
++        self.assertGreater(bt, 0)
++        self.assertLess(bt, time.time())
+ 
+-    @skipUnless(POSIX)
++    @unittest.skipUnless(POSIX, 'posix only')
+     def test_PAGESIZE(self):
+         # pagesize is used internally to perform different calculations
+         # and it's determined by using SC_PAGE_SIZE; make sure
+@@ -353,42 +635,6 @@
+         import resource
+         self.assertEqual(os.sysconf("SC_PAGE_SIZE"), resource.getpagesize())
+ 
+-    def test_deprecated_apis(self):
+-        warnings.filterwarnings("error")
+-        p = psutil.Process(os.getpid())
+-        try:
+-            self.assertRaises(DeprecationWarning, __import__, 'psutil.error')
+-            self.assertRaises(DeprecationWarning, psutil.virtmem_usage)
+-            self.assertRaises(DeprecationWarning, psutil.used_phymem)
+-            self.assertRaises(DeprecationWarning, psutil.avail_phymem)
+-            self.assertRaises(DeprecationWarning, psutil.total_virtmem)
+-            self.assertRaises(DeprecationWarning, psutil.used_virtmem)
+-            self.assertRaises(DeprecationWarning, psutil.avail_virtmem)
+-            self.assertRaises(DeprecationWarning, psutil.phymem_usage)
+-            self.assertRaises(DeprecationWarning, psutil.get_process_list)
+-            self.assertRaises(DeprecationWarning, psutil.get_process_list)
+-            if LINUX:
+-                self.assertRaises(DeprecationWarning, psutil.phymem_buffers)
+-                self.assertRaises(DeprecationWarning, psutil.cached_phymem)
+-            try:
+-                p.nice
+-            except DeprecationWarning:
+-                pass
+-            else:
+-                self.fail("p.nice didn't raise DeprecationWarning")
+-        finally:
+-            warnings.resetwarnings()
+-
+-    def test_deprecated_apis_retval(self):
+-        warnings.filterwarnings("ignore")
+-        p = psutil.Process(os.getpid())
+-        try:
+-            self.assertEqual(psutil.total_virtmem(), psutil.swap_memory().total)
+-            self.assertEqual(psutil.get_process_list(), list(psutil.process_iter()))
+-            self.assertEqual(p.nice, p.get_nice())
+-        finally:
+-            warnings.resetwarnings()
+-
+     def test_virtual_memory(self):
+         mem = psutil.virtual_memory()
+         assert mem.total > 0, mem
+@@ -397,51 +643,58 @@
+         assert mem.used > 0, mem
+         assert mem.free >= 0, mem
+         for name in mem._fields:
++            value = getattr(mem, name)
++            if name != 'percent':
++                self.assertIsInstance(value, (int, long))
+             if name != 'total':
+-                value = getattr(mem, name)
+                 if not value >= 0:
+                     self.fail("%r < 0 (%s)" % (name, value))
+                 if value > mem.total:
+-                    self.fail("%r > total (total=%s, %s=%s)" \
++                    self.fail("%r > total (total=%s, %s=%s)"
+                               % (name, mem.total, name, value))
+ 
+     def test_swap_memory(self):
+         mem = psutil.swap_memory()
+-        assert mem.total > 0, mem
++        assert mem.total >= 0, mem
+         assert mem.used >= 0, mem
+-        assert mem.free > 0, mem
++        if mem.total > 0:
++            # likely a system with no swap partition
++            assert mem.free > 0, mem
++        else:
++            assert mem.free == 0, mem
+         assert 0 <= mem.percent <= 100, mem
+         assert mem.sin >= 0, mem
+         assert mem.sout >= 0, mem
+ 
+     def test_pid_exists(self):
+         sproc = get_test_subprocess(wait=True)
+-        assert psutil.pid_exists(sproc.pid)
++        self.assertTrue(psutil.pid_exists(sproc.pid))
+         p = psutil.Process(sproc.pid)
+         p.kill()
+         p.wait()
+         self.assertFalse(psutil.pid_exists(sproc.pid))
+         self.assertFalse(psutil.pid_exists(-1))
++        self.assertEqual(psutil.pid_exists(0), 0 in psutil.pids())
+ 
+     def test_pid_exists_2(self):
+         reap_children()
+-        pids = psutil.get_pid_list()
++        pids = psutil.pids()
+         for pid in pids:
+             try:
+                 assert psutil.pid_exists(pid)
+             except AssertionError:
+                 # in case the process disappeared in meantime fail only
+-                # if it is no longer in get_pid_list()
++                # if it is no longer in psutil.pids()
+                 time.sleep(.1)
+-                if pid in psutil.get_pid_list():
++                if pid in psutil.pids():
+                     self.fail(pid)
+         pids = range(max(pids) + 5000, max(pids) + 6000)
+         for pid in pids:
+-            self.assertFalse(psutil.pid_exists(pid))
++            self.assertFalse(psutil.pid_exists(pid), msg=pid)
+ 
+-    def test_get_pid_list(self):
++    def test_pids(self):
+         plist = [x.pid for x in psutil.process_iter()]
+-        pidlist = psutil.get_pid_list()
++        pidlist = psutil.pids()
+         self.assertEqual(plist.sort(), pidlist.sort())
+         # make sure every pid is unique
+         self.assertEqual(len(pidlist), len(set(pidlist)))
+@@ -455,16 +708,43 @@
+         finally:
+             sys.stdout = stdout
+ 
++    def test_cpu_count(self):
++        logical = psutil.cpu_count()
++        self.assertEqual(logical, len(psutil.cpu_times(percpu=True)))
++        self.assertGreaterEqual(logical, 1)
++        #
++        if LINUX:
++            with open("/proc/cpuinfo") as fd:
++                cpuinfo_data = fd.read()
++            if "physical id" not in cpuinfo_data:
++                raise unittest.SkipTest("cpuinfo doesn't include physical id")
++        physical = psutil.cpu_count(logical=False)
++        self.assertGreaterEqual(physical, 1)
++        self.assertGreaterEqual(logical, physical)
++
+     def test_sys_cpu_times(self):
+         total = 0
+         times = psutil.cpu_times()
+         sum(times)
+         for cp_time in times:
+-            assert isinstance(cp_time, float)
+-            assert cp_time >= 0.0, cp_time
++            self.assertIsInstance(cp_time, float)
++            self.assertGreaterEqual(cp_time, 0.0)
+             total += cp_time
+         self.assertEqual(total, sum(times))
+         str(times)
++        if not WINDOWS:
++            # CPU times are always supposed to increase over time or
++            # remain the same but never go backwards, see:
++            # https://github.com/giampaolo/psutil/issues/392
++            last = psutil.cpu_times()
++            for x in range(100):
++                new = psutil.cpu_times()
++                for field in new._fields:
++                    new_t = getattr(new, field)
++                    last_t = getattr(last, field)
++                    self.assertGreaterEqual(new_t, last_t,
++                                            msg="%s %s" % (new_t, last_t))
++                last = new
+ 
+     def test_sys_cpu_times2(self):
+         t1 = sum(psutil.cpu_times())
+@@ -479,18 +759,34 @@
+             total = 0
+             sum(times)
+             for cp_time in times:
+-                assert isinstance(cp_time, float)
+-                assert cp_time >= 0.0, cp_time
++                self.assertIsInstance(cp_time, float)
++                self.assertGreaterEqual(cp_time, 0.0)
+                 total += cp_time
+             self.assertEqual(total, sum(times))
+             str(times)
+         self.assertEqual(len(psutil.cpu_times(percpu=True)[0]),
+                          len(psutil.cpu_times(percpu=False)))
++        if not WINDOWS:
++            # CPU times are always supposed to increase over time or
++            # remain the same but never go backwards, see:
++            # https://github.com/giampaolo/psutil/issues/392
++            last = psutil.cpu_times(percpu=True)
++            for x in range(100):
++                new = psutil.cpu_times(percpu=True)
++                for index in range(len(new)):
++                    newcpu = new[index]
++                    lastcpu = last[index]
++                    for field in newcpu._fields:
++                        new_t = getattr(newcpu, field)
++                        last_t = getattr(lastcpu, field)
++                        self.assertGreaterEqual(
++                            new_t, last_t, msg="%s %s" % (lastcpu, newcpu))
++                last = new
+ 
+     def test_sys_per_cpu_times2(self):
+         tot1 = psutil.cpu_times(percpu=True)
+         stop_at = time.time() + 0.1
+-        while 1:
++        while True:
+             if time.time() >= stop_at:
+                 break
+         tot2 = psutil.cpu_times(percpu=True)
+@@ -502,26 +798,26 @@
+         self.fail()
+ 
+     def _test_cpu_percent(self, percent):
+-        assert isinstance(percent, float), percent
+-        assert percent >= 0.0, percent
+-        assert percent <= 100.0, percent
++        self.assertIsInstance(percent, float)
++        self.assertGreaterEqual(percent, 0.0)
++        self.assertLessEqual(percent, 100.0 * psutil.cpu_count())
+ 
+     def test_sys_cpu_percent(self):
+         psutil.cpu_percent(interval=0.001)
+-        for x in range(1000):
++        for x in range(100):
+             self._test_cpu_percent(psutil.cpu_percent(interval=None))
+ 
+     def test_sys_per_cpu_percent(self):
+         self.assertEqual(len(psutil.cpu_percent(interval=0.001, percpu=True)),
+-                         psutil.NUM_CPUS)
+-        for x in range(1000):
++                         psutil.cpu_count())
++        for x in range(100):
+             percents = psutil.cpu_percent(interval=None, percpu=True)
+             for percent in percents:
+                 self._test_cpu_percent(percent)
+ 
+     def test_sys_cpu_times_percent(self):
+         psutil.cpu_times_percent(interval=0.001)
+-        for x in range(1000):
++        for x in range(100):
+             cpu = psutil.cpu_times_percent(interval=None)
+             for percent in cpu:
+                 self._test_cpu_percent(percent)
+@@ -530,14 +826,16 @@
+     def test_sys_per_cpu_times_percent(self):
+         self.assertEqual(len(psutil.cpu_times_percent(interval=0.001,
+                                                       percpu=True)),
+-                         psutil.NUM_CPUS)
+-        for x in range(1000):
++                         psutil.cpu_count())
++        for x in range(100):
+             cpus = psutil.cpu_times_percent(interval=None, percpu=True)
+             for cpu in cpus:
+                 for percent in cpu:
+                     self._test_cpu_percent(percent)
+                 self._test_cpu_percent(sum(cpu))
+ 
++    @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
++                     "os.statvfs() function not available on this platform")
+     def test_disk_usage(self):
+         usage = psutil.disk_usage(os.getcwd())
+         assert usage.total > 0, usage
+@@ -546,40 +844,88 @@
+         assert usage.total > usage.used, usage
+         assert usage.total > usage.free, usage
+         assert 0 <= usage.percent <= 100, usage.percent
++        if hasattr(shutil, 'disk_usage'):
++            # py >= 3.3, see: http://bugs.python.org/issue12442
++            shutil_usage = shutil.disk_usage(os.getcwd())
++            tolerance = 5 * 1024 * 1024  # 5MB
++            self.assertEqual(usage.total, shutil_usage.total)
++            self.assertAlmostEqual(usage.free, shutil_usage.free,
++                                   delta=tolerance)
++            self.assertAlmostEqual(usage.used, shutil_usage.used,
++                                   delta=tolerance)
+ 
+         # if path does not exist OSError ENOENT is expected across
+         # all platforms
+         fname = tempfile.mktemp()
+         try:
+             psutil.disk_usage(fname)
+-        except OSError:
+-            err = sys.exc_info()[1]
++        except OSError as err:
+             if err.args[0] != errno.ENOENT:
+                 raise
+         else:
+             self.fail("OSError not raised")
+ 
++    @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
++                     "os.statvfs() function not available on this platform")
++    def test_disk_usage_unicode(self):
++        # see: https://github.com/giampaolo/psutil/issues/416
++        # XXX this test is not really reliable as it always fails on
++        # Python 3.X (2.X is fine)
++        try:
++            safe_rmdir(TESTFN_UNICODE)
++            os.mkdir(TESTFN_UNICODE)
++            psutil.disk_usage(TESTFN_UNICODE)
++            safe_rmdir(TESTFN_UNICODE)
++        except UnicodeEncodeError:
++            pass
++
++    @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'),
++                     "os.statvfs() function not available on this platform")
++    @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
+     def test_disk_partitions(self):
+-        for disk in psutil.disk_partitions(all=False):
++        # all = False
++        ls = psutil.disk_partitions(all=False)
++        # on travis we get:
++        #     self.assertEqual(p.cpu_affinity(), [n])
++        # AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, 7,... != [0]
++        self.assertTrue(ls, msg=ls)
++        for disk in ls:
+             if WINDOWS and 'cdrom' in disk.opts:
+                 continue
+-            assert os.path.exists(disk.device), disk
+-            assert os.path.isdir(disk.mountpoint), disk
++            if not POSIX:
++                assert os.path.exists(disk.device), disk
++            else:
++                # we cannot make any assumption about this, see:
++                # http://goo.gl/p9c43
++                disk.device
++            if SUNOS:
++                # on solaris apparently mount points can also be files
++                assert os.path.exists(disk.mountpoint), disk
++            else:
++                assert os.path.isdir(disk.mountpoint), disk
+             assert disk.fstype, disk
+-            assert isinstance(disk.opts, str)
++            self.assertIsInstance(disk.opts, str)
++
++        # all = True
++        ls = psutil.disk_partitions(all=True)
++        self.assertTrue(ls, msg=ls)
+         for disk in psutil.disk_partitions(all=True):
+             if not WINDOWS:
+                 try:
+                     os.stat(disk.mountpoint)
+-                except OSError:
+-                    # http://mail.python.org/pipermail/python-dev/2012-June/120787.html
+-                    err = sys.exc_info()[1]
++                except OSError as err:
++                    # http://mail.python.org/pipermail/python-dev/
++                    #     2012-June/120787.html
+                     if err.errno not in (errno.EPERM, errno.EACCES):
+                         raise
+                 else:
+-                    assert os.path.isdir(disk.mountpoint), disk.mountpoint
+-            assert isinstance(disk.fstype, str)
+-            assert isinstance(disk.opts, str)
++                    if SUNOS:
++                        # on solaris apparently mount points can also be files
++                        assert os.path.exists(disk.mountpoint), disk
++                    else:
++                        assert os.path.isdir(disk.mountpoint), disk
++            self.assertIsInstance(disk.fstype, str)
++            self.assertIsInstance(disk.opts, str)
+ 
+         def find_mount_point(path):
+             path = os.path.abspath(path)
+@@ -592,7 +938,24 @@
+         self.assertIn(mount, mounts)
+         psutil.disk_usage(mount)
+ 
+-    def test_network_io_counters(self):
++    @skip_on_access_denied()
++    def test_net_connections(self):
++        def check(cons, families, types_):
++            for conn in cons:
++                self.assertIn(conn.family, families, msg=conn)
++                if conn.family != getattr(socket, 'AF_UNIX', object()):
++                    self.assertIn(conn.type, types_, msg=conn)
++
++        from psutil._common import conn_tmap
++        for kind, groups in conn_tmap.items():
++            if SUNOS and kind == 'unix':
++                continue
++            families, types_ = groups
++            cons = psutil.net_connections(kind)
++            self.assertEqual(len(cons), len(set(cons)))
++            check(cons, families, types_)
++
++    def test_net_io_counters(self):
+         def check_ntuple(nt):
+             self.assertEqual(nt[0], nt.bytes_sent)
+             self.assertEqual(nt[1], nt.bytes_recv)
+@@ -611,14 +974,79 @@
+             assert nt.dropin >= 0, nt
+             assert nt.dropout >= 0, nt
+ 
+-        ret = psutil.network_io_counters(pernic=False)
++        ret = psutil.net_io_counters(pernic=False)
+         check_ntuple(ret)
+-        ret = psutil.network_io_counters(pernic=True)
+-        assert ret != []
++        ret = psutil.net_io_counters(pernic=True)
++        self.assertNotEqual(ret, [])
+         for key in ret:
+-            assert key
++            self.assertTrue(key)
+             check_ntuple(ret[key])
+ 
++    def test_net_if_addrs(self):
++        nics = psutil.net_if_addrs()
++        assert nics, nics
++
++        # Not reliable on all platforms (net_if_addrs() reports more
++        # interfaces).
++        # self.assertEqual(sorted(nics.keys()),
++        #                  sorted(psutil.net_io_counters(pernic=True).keys()))
++
++        families = set([socket.AF_INET, AF_INET6, psutil.AF_LINK])
++        for nic, addrs in nics.items():
++            self.assertEqual(len(set(addrs)), len(addrs))
++            for addr in addrs:
++                self.assertIsInstance(addr.family, int)
++                self.assertIsInstance(addr.address, str)
++                self.assertIsInstance(addr.netmask, (str, type(None)))
++                self.assertIsInstance(addr.broadcast, (str, type(None)))
++                self.assertIn(addr.family, families)
++                if sys.version_info >= (3, 4):
++                    self.assertIsInstance(addr.family, enum.IntEnum)
++                if addr.family == socket.AF_INET:
++                    s = socket.socket(addr.family)
++                    with contextlib.closing(s):
++                        s.bind((addr.address, 0))
++                elif addr.family == socket.AF_INET6:
++                    info = socket.getaddrinfo(
++                        addr.address, 0, socket.AF_INET6, socket.SOCK_STREAM,
++                        0, socket.AI_PASSIVE)[0]
++                    af, socktype, proto, canonname, sa = info
++                    s = socket.socket(af, socktype, proto)
++                    with contextlib.closing(s):
++                        s.bind(sa)
++                for ip in (addr.address, addr.netmask, addr.broadcast):
++                    if ip is not None:
++                        # TODO: skip AF_INET6 for now because I get:
++                        # AddressValueError: Only hex digits permitted in
++                        # u'c6f3%lxcbr0' in u'fe80::c8e0:fff:fe54:c6f3%lxcbr0'
++                        if addr.family != AF_INET6:
++                            check_ip_address(ip, addr.family)
++
++        if BSD or OSX or SUNOS:
++            if hasattr(socket, "AF_LINK"):
++                self.assertEqual(psutil.AF_LINK, socket.AF_LINK)
++        elif LINUX:
++            self.assertEqual(psutil.AF_LINK, socket.AF_PACKET)
++        elif WINDOWS:
++            self.assertEqual(psutil.AF_LINK, -1)
++
++    @unittest.skipIf(TRAVIS, "EPERM on travis")
++    def test_net_if_stats(self):
++        nics = psutil.net_if_stats()
++        assert nics, nics
++        all_duplexes = (psutil.NIC_DUPLEX_FULL,
++                        psutil.NIC_DUPLEX_HALF,
++                        psutil.NIC_DUPLEX_UNKNOWN)
++        for nic, stats in nics.items():
++            isup, duplex, speed, mtu = stats
++            self.assertIsInstance(isup, bool)
++            self.assertIn(duplex, all_duplexes)
++            self.assertIn(duplex, all_duplexes)
++            self.assertGreaterEqual(speed, 0)
++            self.assertGreaterEqual(mtu, 0)
++
++    @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
++                     '/proc/diskstats not available on this linux version')
+     def test_disk_io_counters(self):
+         def check_ntuple(nt):
+             self.assertEqual(nt[0], nt.read_count)
+@@ -644,14 +1072,14 @@
+             check_ntuple(ret[key])
+             if LINUX and key[-1].isdigit():
+                 # if 'sda1' is listed 'sda' shouldn't, see:
+-                # http://code.google.com/p/psutil/issues/detail?id=338
++                # https://github.com/giampaolo/psutil/issues/338
+                 while key[-1].isdigit():
+                     key = key[:-1]
+-                assert key not in ret, (key, ret.keys())
++                self.assertNotIn(key, ret.keys())
+ 
+-    def test_get_users(self):
+-        users = psutil.get_users()
+-        assert users
++    def test_users(self):
++        users = psutil.users()
++        self.assertNotEqual(users, [])
+         for user in users:
+             assert user.name, user
+             user.terminal
+@@ -659,40 +1087,55 @@
+             assert user.started > 0.0, user
+             datetime.datetime.fromtimestamp(user.started)
+ 
+-    # ====================
+-    # Process object tests
+-    # ====================
++
++# ===================================================================
++# --- psutil.Process class tests
++# ===================================================================
++
++class TestProcess(unittest.TestCase):
++    """Tests for psutil.Process class."""
++
++    def setUp(self):
++        safe_remove(TESTFN)
++
++    def tearDown(self):
++        reap_children()
++
++    def test_pid(self):
++        self.assertEqual(psutil.Process().pid, os.getpid())
++        sproc = get_test_subprocess()
++        self.assertEqual(psutil.Process(sproc.pid).pid, sproc.pid)
+ 
+     def test_kill(self):
+         sproc = get_test_subprocess(wait=True)
+         test_pid = sproc.pid
+         p = psutil.Process(test_pid)
+-        name = p.name
+         p.kill()
+-        p.wait()
+-        self.assertFalse(psutil.pid_exists(test_pid) and name == PYTHON)
++        sig = p.wait()
++        self.assertFalse(psutil.pid_exists(test_pid))
++        if POSIX:
++            self.assertEqual(sig, signal.SIGKILL)
+ 
+     def test_terminate(self):
+         sproc = get_test_subprocess(wait=True)
+         test_pid = sproc.pid
+         p = psutil.Process(test_pid)
+-        name = p.name
+         p.terminate()
+-        p.wait()
+-        self.assertFalse(psutil.pid_exists(test_pid) and name == PYTHON)
++        sig = p.wait()
++        self.assertFalse(psutil.pid_exists(test_pid))
++        if POSIX:
++            self.assertEqual(sig, signal.SIGTERM)
+ 
+     def test_send_signal(self):
+-        if POSIX:
+-            sig = signal.SIGKILL
+-        else:
+-            sig = signal.SIGTERM
++        sig = signal.SIGKILL if POSIX else signal.SIGTERM
+         sproc = get_test_subprocess()
+         test_pid = sproc.pid
+         p = psutil.Process(test_pid)
+-        name = p.name
+         p.send_signal(sig)
+-        p.wait()
+-        self.assertFalse(psutil.pid_exists(test_pid) and name == PYTHON)
++        exit_sig = p.wait()
++        self.assertFalse(psutil.pid_exists(test_pid))
++        if POSIX:
++            self.assertEqual(exit_sig, sig)
+ 
+     def test_wait(self):
+         # check exit code signal
+@@ -700,7 +1143,7 @@
+         p = psutil.Process(sproc.pid)
+         p.kill()
+         code = p.wait()
+-        if os.name == 'posix':
++        if POSIX:
+             self.assertEqual(code, signal.SIGKILL)
+         else:
+             self.assertEqual(code, 0)
+@@ -710,7 +1153,7 @@
+         p = psutil.Process(sproc.pid)
+         p.terminate()
+         code = p.wait()
+-        if os.name == 'posix':
++        if POSIX:
+             self.assertEqual(code, signal.SIGTERM)
+         else:
+             self.assertEqual(code, 0)
+@@ -735,22 +1178,23 @@
+         # test timeout
+         sproc = get_test_subprocess()
+         p = psutil.Process(sproc.pid)
+-        p.name
++        p.name()
+         self.assertRaises(psutil.TimeoutExpired, p.wait, 0.01)
+ 
+         # timeout < 0 not allowed
+         self.assertRaises(ValueError, p.wait, -1)
+ 
+-    @skipUnless(POSIX)
++    # XXX why is this skipped on Windows?
++    @unittest.skipUnless(POSIX, 'skipped on Windows')
+     def test_wait_non_children(self):
+         # test wait() against processes which are not our children
+         code = "import sys;"
+         code += "from subprocess import Popen, PIPE;"
+-        code += "cmd = ['%s', '-c', 'import time; time.sleep(10)'];" %PYTHON
++        code += "cmd = ['%s', '-c', 'import time; time.sleep(60)'];" % PYTHON
+         code += "sp = Popen(cmd, stdout=PIPE);"
+         code += "sys.stdout.write(str(sp.pid));"
+-        sproc = get_test_subprocess([PYTHON, "-c", code], stdout=subprocess.PIPE)
+-
++        sproc = get_test_subprocess([PYTHON, "-c", code],
++                                    stdout=subprocess.PIPE)
+         grandson_pid = int(sproc.stdout.read())
+         grandson_proc = psutil.Process(grandson_pid)
+         try:
+@@ -769,7 +1213,7 @@
+         self.assertRaises(psutil.TimeoutExpired, p.wait, 0)
+         p.kill()
+         stop_at = time.time() + 2
+-        while 1:
++        while True:
+             try:
+                 code = p.wait(0)
+             except psutil.TimeoutExpired:
+@@ -777,27 +1221,27 @@
+                     raise
+             else:
+                 break
+-        if os.name == 'posix':
++        if POSIX:
+             self.assertEqual(code, signal.SIGKILL)
+         else:
+             self.assertEqual(code, 0)
+         self.assertFalse(p.is_running())
+ 
+     def test_cpu_percent(self):
+-        p = psutil.Process(os.getpid())
+-        p.get_cpu_percent(interval=0.001)
+-        p.get_cpu_percent(interval=0.001)
++        p = psutil.Process()
++        p.cpu_percent(interval=0.001)
++        p.cpu_percent(interval=0.001)
+         for x in range(100):
+-            percent = p.get_cpu_percent(interval=None)
+-            assert isinstance(percent, float)
+-            assert percent >= 0.0, percent
+-            if os.name != 'posix':
+-                assert percent <= 100.0, percent
++            percent = p.cpu_percent(interval=None)
++            self.assertIsInstance(percent, float)
++            self.assertGreaterEqual(percent, 0.0)
++            if not POSIX:
++                self.assertLessEqual(percent, 100.0)
+             else:
+-                assert percent >= 0.0, percent
++                self.assertGreaterEqual(percent, 0.0)
+ 
+     def test_cpu_times(self):
+-        times = psutil.Process(os.getpid()).get_cpu_times()
++        times = psutil.Process().cpu_times()
+         assert (times.user > 0.0) or (times.system > 0.0), times
+         # make sure returned values can be pretty printed with strftime
+         time.strftime("%H:%M:%S", time.localtime(times.user))
+@@ -809,25 +1253,26 @@
+     # XXX fails on OSX: not sure if it's for os.times(). We should
+     # try this with Python 2.7 and re-enable the test.
+ 
+-    @skipUnless(sys.version_info > (2, 6, 1) and not OSX)
++    @unittest.skipUnless(sys.version_info > (2, 6, 1) and not OSX,
++                         'os.times() is not reliable on this Python version')
+     def test_cpu_times2(self):
+-        user_time, kernel_time = psutil.Process(os.getpid()).get_cpu_times()
++        user_time, kernel_time = psutil.Process().cpu_times()
+         utime, ktime = os.times()[:2]
+ 
+         # Use os.times()[:2] as base values to compare our results
+         # using a tolerance  of +/- 0.1 seconds.
+         # It will fail if the difference between the values is > 0.1s.
+         if (max([user_time, utime]) - min([user_time, utime])) > 0.1:
+-            self.fail("expected: %s, found: %s" %(utime, user_time))
++            self.fail("expected: %s, found: %s" % (utime, user_time))
+ 
+         if (max([kernel_time, ktime]) - min([kernel_time, ktime])) > 0.1:
+-            self.fail("expected: %s, found: %s" %(ktime, kernel_time))
++            self.fail("expected: %s, found: %s" % (ktime, kernel_time))
+ 
+     def test_create_time(self):
+         sproc = get_test_subprocess(wait=True)
+         now = time.time()
+         p = psutil.Process(sproc.pid)
+-        create_time = p.create_time
++        create_time = p.create_time()
+ 
+         # Use time.time() as base value to compare our result using a
+         # tolerance of +/- 1 second.
+@@ -838,45 +1283,48 @@
+                       % (now, create_time, difference))
+ 
+         # make sure returned value can be pretty printed with strftime
+-        time.strftime("%Y %m %d %H:%M:%S", time.localtime(p.create_time))
++        time.strftime("%Y %m %d %H:%M:%S", time.localtime(p.create_time()))
+ 
+-    @skipIf(WINDOWS)
++    @unittest.skipIf(WINDOWS, 'Windows only')
+     def test_terminal(self):
+-        tty = sh('tty')
+-        p = psutil.Process(os.getpid())
+-        self.assertEqual(p.terminal, tty)
+-
+-    @skipIf(OSX, warn=False)
+-    def test_get_io_counters(self):
+-        p = psutil.Process(os.getpid())
++        terminal = psutil.Process().terminal()
++        if sys.stdin.isatty():
++            self.assertEqual(terminal, sh('tty'))
++        else:
++            assert terminal, repr(terminal)
++
++    @unittest.skipUnless(LINUX or BSD or WINDOWS,
++                         'not available on this platform')
++    @skip_on_not_implemented(only_if=LINUX)
++    def test_io_counters(self):
++        p = psutil.Process()
+         # test reads
+-        io1 = p.get_io_counters()
+-        f = open(PYTHON, 'rb')
+-        f.read()
+-        f.close()
+-        io2 = p.get_io_counters()
++        io1 = p.io_counters()
++        with open(PYTHON, 'rb') as f:
++            f.read()
++        io2 = p.io_counters()
+         if not BSD:
+             assert io2.read_count > io1.read_count, (io1, io2)
+             self.assertEqual(io2.write_count, io1.write_count)
+         assert io2.read_bytes >= io1.read_bytes, (io1, io2)
+         assert io2.write_bytes >= io1.write_bytes, (io1, io2)
+         # test writes
+-        io1 = p.get_io_counters()
+-        f = tempfile.TemporaryFile()
+-        if PY3:
+-            f.write(bytes("x" * 1000000, 'ascii'))
+-        else:
+-            f.write("x" * 1000000)
+-        f.close()
+-        io2 = p.get_io_counters()
++        io1 = p.io_counters()
++        with tempfile.TemporaryFile(prefix=TESTFILE_PREFIX) as f:
++            if PY3:
++                f.write(bytes("x" * 1000000, 'ascii'))
++            else:
++                f.write("x" * 1000000)
++        io2 = p.io_counters()
+         assert io2.write_count >= io1.write_count, (io1, io2)
+         assert io2.write_bytes >= io1.write_bytes, (io1, io2)
+         assert io2.read_count >= io1.read_count, (io1, io2)
+         assert io2.read_bytes >= io1.read_bytes, (io1, io2)
+ 
+-    # Linux and Windows Vista+
+-    @skipUnless(hasattr(psutil.Process, 'get_ionice'))
+-    def test_get_set_ionice(self):
++    @unittest.skipUnless(LINUX or (WINDOWS and get_winver() >= WIN_VISTA),
++                         'Linux and Windows Vista only')
++    @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
++    def test_ionice(self):
+         if LINUX:
+             from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT,
+                                 IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE)
+@@ -884,76 +1332,106 @@
+             self.assertEqual(IOPRIO_CLASS_RT, 1)
+             self.assertEqual(IOPRIO_CLASS_BE, 2)
+             self.assertEqual(IOPRIO_CLASS_IDLE, 3)
+-            p = psutil.Process(os.getpid())
++            p = psutil.Process()
+             try:
+-                p.set_ionice(2)
+-                ioclass, value = p.get_ionice()
++                p.ionice(2)
++                ioclass, value = p.ionice()
++                if enum is not None:
++                    self.assertIsInstance(ioclass, enum.IntEnum)
+                 self.assertEqual(ioclass, 2)
+                 self.assertEqual(value, 4)
+                 #
+-                p.set_ionice(3)
+-                ioclass, value = p.get_ionice()
++                p.ionice(3)
++                ioclass, value = p.ionice()
+                 self.assertEqual(ioclass, 3)
+                 self.assertEqual(value, 0)
+                 #
+-                p.set_ionice(2, 0)
+-                ioclass, value = p.get_ionice()
++                p.ionice(2, 0)
++                ioclass, value = p.ionice()
+                 self.assertEqual(ioclass, 2)
+                 self.assertEqual(value, 0)
+-                p.set_ionice(2, 7)
+-                ioclass, value = p.get_ionice()
++                p.ionice(2, 7)
++                ioclass, value = p.ionice()
+                 self.assertEqual(ioclass, 2)
+                 self.assertEqual(value, 7)
+-                self.assertRaises(ValueError, p.set_ionice, 2, 10)
++                self.assertRaises(ValueError, p.ionice, 2, 10)
+             finally:
+-                p.set_ionice(IOPRIO_CLASS_NONE)
++                p.ionice(IOPRIO_CLASS_NONE)
+         else:
+-            p = psutil.Process(os.getpid())
+-            original = p.get_ionice()
++            p = psutil.Process()
++            original = p.ionice()
++            self.assertIsInstance(original, int)
+             try:
+                 value = 0  # very low
+                 if original == value:
+                     value = 1  # low
+-                p.set_ionice(value)
+-                self.assertEqual(p.get_ionice(), value)
++                p.ionice(value)
++                self.assertEqual(p.ionice(), value)
+             finally:
+-                p.set_ionice(original)
++                p.ionice(original)
+             #
+-            self.assertRaises(ValueError, p.set_ionice, 3)
+-            self.assertRaises(TypeError, p.set_ionice, 2, 1)
++            self.assertRaises(ValueError, p.ionice, 3)
++            self.assertRaises(TypeError, p.ionice, 2, 1)
+ 
+-    def test_get_num_threads(self):
++    @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
++                         "only available on Linux >= 2.6.36")
++    def test_rlimit_get(self):
++        import resource
++        p = psutil.Process(os.getpid())
++        names = [x for x in dir(psutil) if x.startswith('RLIMIT')]
++        assert names, names
++        for name in names:
++            value = getattr(psutil, name)
++            self.assertGreaterEqual(value, 0)
++            if name in dir(resource):
++                self.assertEqual(value, getattr(resource, name))
++                self.assertEqual(p.rlimit(value), resource.getrlimit(value))
++            else:
++                ret = p.rlimit(value)
++                self.assertEqual(len(ret), 2)
++                self.assertGreaterEqual(ret[0], -1)
++                self.assertGreaterEqual(ret[1], -1)
++
++    @unittest.skipUnless(LINUX and RLIMIT_SUPPORT,
++                         "only available on Linux >= 2.6.36")
++    def test_rlimit_set(self):
++        sproc = get_test_subprocess()
++        p = psutil.Process(sproc.pid)
++        p.rlimit(psutil.RLIMIT_NOFILE, (5, 5))
++        self.assertEqual(p.rlimit(psutil.RLIMIT_NOFILE), (5, 5))
++
++    def test_num_threads(self):
+         # on certain platforms such as Linux we might test for exact
+         # thread number, since we always have with 1 thread per process,
+         # but this does not apply across all platforms (OSX, Windows)
+-        p = psutil.Process(os.getpid())
+-        step1 = p.get_num_threads()
++        p = psutil.Process()
++        step1 = p.num_threads()
+ 
+         thread = ThreadTask()
+         thread.start()
+         try:
+-            step2 = p.get_num_threads()
++            step2 = p.num_threads()
+             self.assertEqual(step2, step1 + 1)
+             thread.stop()
+         finally:
+             if thread._running:
+                 thread.stop()
+ 
+-    @skipUnless(WINDOWS)
+-    def test_get_num_handles(self):
++    @unittest.skipUnless(WINDOWS, 'Windows only')
++    def test_num_handles(self):
+         # a better test is done later into test/_windows.py
+-        p = psutil.Process(os.getpid())
+-        assert p.get_num_handles() > 0
++        p = psutil.Process()
++        self.assertGreater(p.num_handles(), 0)
+ 
+-    def test_get_threads(self):
+-        p = psutil.Process(os.getpid())
+-        step1 = p.get_threads()
++    def test_threads(self):
++        p = psutil.Process()
++        step1 = p.threads()
+ 
+         thread = ThreadTask()
+         thread.start()
+ 
+         try:
+-            step2 = p.get_threads()
++            step2 = p.threads()
+             self.assertEqual(len(step2), len(step1) + 1)
+             # on Linux, first thread id is supposed to be this process
+             if LINUX:
+@@ -969,35 +1447,35 @@
+             if thread._running:
+                 thread.stop()
+ 
+-    def test_get_memory_info(self):
+-        p = psutil.Process(os.getpid())
++    def test_memory_info(self):
++        p = psutil.Process()
+ 
+         # step 1 - get a base value to compare our results
+-        rss1, vms1 = p.get_memory_info()
+-        percent1 = p.get_memory_percent()
+-        assert rss1 > 0
+-        assert vms1 > 0
++        rss1, vms1 = p.memory_info()
++        percent1 = p.memory_percent()
++        self.assertGreater(rss1, 0)
++        self.assertGreater(vms1, 0)
+ 
+         # step 2 - allocate some memory
+         memarr = [None] * 1500000
+ 
+-        rss2, vms2 = p.get_memory_info()
+-        percent2 = p.get_memory_percent()
++        rss2, vms2 = p.memory_info()
++        percent2 = p.memory_percent()
+         # make sure that the memory usage bumped up
+-        assert rss2 > rss1
+-        assert vms2 >= vms1  # vms might be equal
+-        assert percent2 > percent1
++        self.assertGreater(rss2, rss1)
++        self.assertGreaterEqual(vms2, vms1)  # vms might be equal
++        self.assertGreater(percent2, percent1)
+         del memarr
+ 
+-#    def test_get_ext_memory_info(self):
+-#       # tested later in fetch all test suite
++    # def test_memory_info_ex(self):
++    # # tested later in fetch all test suite
+ 
+-    def test_get_memory_maps(self):
+-        p = psutil.Process(os.getpid())
+-        maps = p.get_memory_maps()
++    def test_memory_maps(self):
++        p = psutil.Process()
++        maps = p.memory_maps()
+         paths = [x for x in maps]
+         self.assertEqual(len(paths), len(set(paths)))
+-        ext_maps = p.get_memory_maps(grouped=False)
++        ext_maps = p.memory_maps(grouped=False)
+ 
+         for nt in maps:
+             if not nt.path.startswith('['):
+@@ -1018,16 +1496,12 @@
+                 elif fname in ('addr', 'perms'):
+                     assert value, value
+                 else:
+-                    assert isinstance(value, (int, long))
++                    self.assertIsInstance(value, (int, long))
+                     assert value >= 0, value
+ 
+-    def test_get_memory_percent(self):
+-        p = psutil.Process(os.getpid())
+-        assert p.get_memory_percent() > 0.0
+-
+-    def test_pid(self):
+-        sproc = get_test_subprocess()
+-        self.assertEqual(psutil.Process(sproc.pid).pid, sproc.pid)
++    def test_memory_percent(self):
++        p = psutil.Process()
++        self.assertGreater(p.memory_percent(), 0.0)
+ 
+     def test_is_running(self):
+         sproc = get_test_subprocess(wait=True)
+@@ -1041,7 +1515,7 @@
+ 
+     def test_exe(self):
+         sproc = get_test_subprocess(wait=True)
+-        exe = psutil.Process(sproc.pid).exe
++        exe = psutil.Process(sproc.pid).exe()
+         try:
+             self.assertEqual(exe, PYTHON)
+         except AssertionError:
+@@ -1059,157 +1533,189 @@
+                 self.assertEqual(exe.replace(ver, ''), PYTHON.replace(ver, ''))
+ 
+     def test_cmdline(self):
+-        sproc = get_test_subprocess([PYTHON, "-E"], wait=True)
+-        self.assertEqual(psutil.Process(sproc.pid).cmdline, [PYTHON, "-E"])
++        cmdline = [PYTHON, "-c", "import time; time.sleep(60)"]
++        sproc = get_test_subprocess(cmdline, wait=True)
++        self.assertEqual(' '.join(psutil.Process(sproc.pid).cmdline()),
++                         ' '.join(cmdline))
+ 
+     def test_name(self):
+         sproc = get_test_subprocess(PYTHON, wait=True)
+-        name = psutil.Process(sproc.pid).name.lower()
++        name = psutil.Process(sproc.pid).name().lower()
+         pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
+         assert pyexe.startswith(name), (pyexe, name)
+ 
+-    if os.name == 'posix':
+-
+-        def test_uids(self):
+-            p = psutil.Process(os.getpid())
+-            real, effective, saved = p.uids
+-            # os.getuid() refers to "real" uid
+-            self.assertEqual(real, os.getuid())
+-            # os.geteuid() refers to "effective" uid
+-            self.assertEqual(effective, os.geteuid())
+-            # no such thing as os.getsuid() ("saved" uid), but starting
+-            # from python 2.7 we have os.getresuid()[2]
+-            if hasattr(os, "getresuid"):
+-                self.assertEqual(saved, os.getresuid()[2])
+-
+-        def test_gids(self):
+-            p = psutil.Process(os.getpid())
+-            real, effective, saved = p.gids
+-            # os.getuid() refers to "real" uid
+-            self.assertEqual(real, os.getgid())
+-            # os.geteuid() refers to "effective" uid
+-            self.assertEqual(effective, os.getegid())
+-            # no such thing as os.getsuid() ("saved" uid), but starting
+-            # from python 2.7 we have os.getresgid()[2]
+-            if hasattr(os, "getresuid"):
+-                self.assertEqual(saved, os.getresgid()[2])
+-
+-        def test_nice(self):
+-            p = psutil.Process(os.getpid())
+-            self.assertRaises(TypeError, p.set_nice, "str")
++    @unittest.skipUnless(POSIX, "posix only")
++    # TODO: add support for other compilers
++    @unittest.skipUnless(which("gcc"), "gcc not available")
++    def test_prog_w_funky_name(self):
++        # Test that name(), exe() and cmdline() correctly handle programs
++        # with funky chars such as spaces and ")", see:
++        # https://github.com/giampaolo/psutil/issues/628
++        funky_name = "/tmp/foo bar )"
++        _, c_file = tempfile.mkstemp(prefix='psutil-', suffix='.c', dir="/tmp")
++        self.addCleanup(lambda: safe_remove(c_file))
++        self.addCleanup(lambda: safe_remove(funky_name))
++        with open(c_file, "w") as f:
++            f.write("void main() { pause(); }")
++        subprocess.check_call(["gcc", c_file, "-o", funky_name])
++        sproc = get_test_subprocess(
++            [funky_name, "arg1", "arg2", "", "arg3", ""])
++        p = psutil.Process(sproc.pid)
++        # ...in order to try to prevent occasional failures on travis
++        wait_for_pid(p.pid)
++        self.assertEqual(p.name(), "foo bar )")
++        self.assertEqual(p.exe(), "/tmp/foo bar )")
++        self.assertEqual(
++            p.cmdline(), ["/tmp/foo bar )", "arg1", "arg2", "", "arg3", ""])
++
++    @unittest.skipUnless(POSIX, 'posix only')
++    def test_uids(self):
++        p = psutil.Process()
++        real, effective, saved = p.uids()
++        # os.getuid() refers to "real" uid
++        self.assertEqual(real, os.getuid())
++        # os.geteuid() refers to "effective" uid
++        self.assertEqual(effective, os.geteuid())
++        # no such thing as os.getsuid() ("saved" uid), but starting
++        # from python 2.7 we have os.getresuid()[2]
++        if hasattr(os, "getresuid"):
++            self.assertEqual(saved, os.getresuid()[2])
++
++    @unittest.skipUnless(POSIX, 'posix only')
++    def test_gids(self):
++        p = psutil.Process()
++        real, effective, saved = p.gids()
++        # os.getuid() refers to "real" uid
++        self.assertEqual(real, os.getgid())
++        # os.geteuid() refers to "effective" uid
++        self.assertEqual(effective, os.getegid())
++        # no such thing as os.getsuid() ("saved" uid), but starting
++        # from python 2.7 we have os.getresgid()[2]
++        if hasattr(os, "getresuid"):
++            self.assertEqual(saved, os.getresgid()[2])
++
++    def test_nice(self):
++        p = psutil.Process()
++        self.assertRaises(TypeError, p.nice, "str")
++        if WINDOWS:
+             try:
+-                try:
+-                    first_nice = p.get_nice()
+-                    p.set_nice(1)
+-                    self.assertEqual(p.get_nice(), 1)
+-                    # going back to previous nice value raises AccessDenied on OSX
+-                    if not OSX:
+-                        p.set_nice(0)
+-                        self.assertEqual(p.get_nice(), 0)
+-                except psutil.AccessDenied:
+-                    pass
++                init = p.nice()
++                if sys.version_info > (3, 4):
++                    self.assertIsInstance(init, enum.IntEnum)
++                else:
++                    self.assertIsInstance(init, int)
++                self.assertEqual(init, psutil.NORMAL_PRIORITY_CLASS)
++                p.nice(psutil.HIGH_PRIORITY_CLASS)
++                self.assertEqual(p.nice(), psutil.HIGH_PRIORITY_CLASS)
++                p.nice(psutil.NORMAL_PRIORITY_CLASS)
++                self.assertEqual(p.nice(), psutil.NORMAL_PRIORITY_CLASS)
++            finally:
++                p.nice(psutil.NORMAL_PRIORITY_CLASS)
++        else:
++            try:
++                first_nice = p.nice()
++                p.nice(1)
++                self.assertEqual(p.nice(), 1)
++                # going back to previous nice value raises
++                # AccessDenied on OSX
++                if not OSX:
++                    p.nice(0)
++                    self.assertEqual(p.nice(), 0)
++            except psutil.AccessDenied:
++                pass
+             finally:
+                 try:
+-                    p.set_nice(first_nice)
++                    p.nice(first_nice)
+                 except psutil.AccessDenied:
+                     pass
+ 
+-    if os.name == 'nt':
+-
+-        def test_nice(self):
+-            p = psutil.Process(os.getpid())
+-            self.assertRaises(TypeError, p.set_nice, "str")
+-            try:
+-                self.assertEqual(p.get_nice(), psutil.NORMAL_PRIORITY_CLASS)
+-                p.set_nice(psutil.HIGH_PRIORITY_CLASS)
+-                self.assertEqual(p.get_nice(), psutil.HIGH_PRIORITY_CLASS)
+-                p.set_nice(psutil.NORMAL_PRIORITY_CLASS)
+-                self.assertEqual(p.get_nice(), psutil.NORMAL_PRIORITY_CLASS)
+-            finally:
+-                p.set_nice(psutil.NORMAL_PRIORITY_CLASS)
+-
+     def test_status(self):
+-        p = psutil.Process(os.getpid())
+-        self.assertEqual(p.status, psutil.STATUS_RUNNING)
+-        self.assertEqual(str(p.status), "running")
+-
+-    def test_status_constants(self):
+-        # STATUS_* constants are supposed to be comparable also by
+-        # using their str representation
+-        self.assertTrue(psutil.STATUS_RUNNING == 0)
+-        self.assertTrue(psutil.STATUS_RUNNING == long(0))
+-        self.assertTrue(psutil.STATUS_RUNNING == 'running')
+-        self.assertFalse(psutil.STATUS_RUNNING == 1)
+-        self.assertFalse(psutil.STATUS_RUNNING == 'sleeping')
+-        self.assertFalse(psutil.STATUS_RUNNING != 0)
+-        self.assertFalse(psutil.STATUS_RUNNING != 'running')
+-        self.assertTrue(psutil.STATUS_RUNNING != 1)
+-        self.assertTrue(psutil.STATUS_RUNNING != 'sleeping')
++        p = psutil.Process()
++        self.assertEqual(p.status(), psutil.STATUS_RUNNING)
+ 
+     def test_username(self):
+         sproc = get_test_subprocess()
+         p = psutil.Process(sproc.pid)
+         if POSIX:
+             import pwd
+-            self.assertEqual(p.username, pwd.getpwuid(os.getuid()).pw_name)
+-        elif WINDOWS:
++            self.assertEqual(p.username(), pwd.getpwuid(os.getuid()).pw_name)
++        elif WINDOWS and 'USERNAME' in os.environ:
+             expected_username = os.environ['USERNAME']
+             expected_domain = os.environ['USERDOMAIN']
+-            domain, username = p.username.split('\\')
++            domain, username = p.username().split('\\')
+             self.assertEqual(domain, expected_domain)
+             self.assertEqual(username, expected_username)
+         else:
+-            p.username
++            p.username()
+ 
+-    @skipIf(not hasattr(psutil.Process, "getcwd"))
+-    def test_getcwd(self):
++    def test_cwd(self):
+         sproc = get_test_subprocess(wait=True)
+         p = psutil.Process(sproc.pid)
+-        self.assertEqual(p.getcwd(), os.getcwd())
++        self.assertEqual(p.cwd(), os.getcwd())
+ 
+-    @skipIf(not hasattr(psutil.Process, "getcwd"))
+-    def test_getcwd_2(self):
+-        cmd = [PYTHON, "-c", "import os, time; os.chdir('..'); time.sleep(10)"]
++    def test_cwd_2(self):
++        cmd = [PYTHON, "-c", "import os, time; os.chdir('..'); time.sleep(60)"]
+         sproc = get_test_subprocess(cmd, wait=True)
+         p = psutil.Process(sproc.pid)
+-        call_until(p.getcwd, "ret == os.path.dirname(os.getcwd())", timeout=1)
++        call_until(p.cwd, "ret == os.path.dirname(os.getcwd())")
+ 
+-    @skipIf(not hasattr(psutil.Process, "get_cpu_affinity"))
++    @unittest.skipUnless(WINDOWS or LINUX or BSD,
++                         'not available on this platform')
++    @unittest.skipIf(LINUX and TRAVIS, "unknown failure on travis")
+     def test_cpu_affinity(self):
+-        p = psutil.Process(os.getpid())
+-        initial = p.get_cpu_affinity()
++        p = psutil.Process()
++        initial = p.cpu_affinity()
++        if hasattr(os, "sched_getaffinity"):
++            self.assertEqual(initial, list(os.sched_getaffinity(p.pid)))
++        self.assertEqual(len(initial), len(set(initial)))
+         all_cpus = list(range(len(psutil.cpu_percent(percpu=True))))
+-        #
++        # setting on travis doesn't seem to work (always return all
++        # CPUs on get):
++        # AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, ... != [0]
+         for n in all_cpus:
+-            p.set_cpu_affinity([n])
+-            self.assertEqual(p.get_cpu_affinity(), [n])
++            p.cpu_affinity([n])
++            self.assertEqual(p.cpu_affinity(), [n])
++            if hasattr(os, "sched_getaffinity"):
++                self.assertEqual(p.cpu_affinity(),
++                                 list(os.sched_getaffinity(p.pid)))
+         #
+-        p.set_cpu_affinity(all_cpus)
+-        self.assertEqual(p.get_cpu_affinity(), all_cpus)
++        p.cpu_affinity(all_cpus)
++        self.assertEqual(p.cpu_affinity(), all_cpus)
++        if hasattr(os, "sched_getaffinity"):
++            self.assertEqual(p.cpu_affinity(),
++                             list(os.sched_getaffinity(p.pid)))
+         #
+-        p.set_cpu_affinity(initial)
++        self.assertRaises(TypeError, p.cpu_affinity, 1)
++        p.cpu_affinity(initial)
++        # it should work with all iterables, not only lists
++        p.cpu_affinity(set(all_cpus))
++        p.cpu_affinity(tuple(all_cpus))
+         invalid_cpu = [len(psutil.cpu_times(percpu=True)) + 10]
+-        self.assertRaises(ValueError, p.set_cpu_affinity, invalid_cpu)
+-
+-    def test_get_open_files(self):
++        self.assertRaises(ValueError, p.cpu_affinity, invalid_cpu)
++        self.assertRaises(ValueError, p.cpu_affinity, range(10000, 11000))
++        self.assertRaises(TypeError, p.cpu_affinity, [0, "1"])
++
++    # TODO
++    @unittest.skipIf(BSD, "broken on BSD, see #595")
++    def test_open_files(self):
+         # current process
+-        p = psutil.Process(os.getpid())
+-        files = p.get_open_files()
++        p = psutil.Process()
++        files = p.open_files()
+         self.assertFalse(TESTFN in files)
+-        f = open(TESTFN, 'w')
+-        call_until(p.get_open_files, "len(ret) != %i" % len(files))
+-        filenames = [x.path for x in p.get_open_files()]
+-        self.assertIn(TESTFN, filenames)
+-        f.close()
++        with open(TESTFN, 'w'):
++            call_until(p.open_files, "len(ret) != %i" % len(files))
++            filenames = [x.path for x in p.open_files()]
++            self.assertIn(TESTFN, filenames)
+         for file in filenames:
+             assert os.path.isfile(file), file
+ 
+         # another process
+-        cmdline = "import time; f = open(r'%s', 'r'); time.sleep(100);" % TESTFN
++        cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN
+         sproc = get_test_subprocess([PYTHON, "-c", cmdline], wait=True)
+         p = psutil.Process(sproc.pid)
++
+         for x in range(100):
+-            filenames = [x.path for x in p.get_open_files()]
++            filenames = [x.path for x in p.open_files()]
+             if TESTFN in filenames:
+                 break
+             time.sleep(.01)
+@@ -1218,224 +1724,217 @@
+         for file in filenames:
+             assert os.path.isfile(file), file
+ 
+-    def test_get_open_files2(self):
++    # TODO
++    @unittest.skipIf(BSD, "broken on BSD, see #595")
++    def test_open_files2(self):
+         # test fd and path fields
+-        fileobj = open(TESTFN, 'w')
+-        p = psutil.Process(os.getpid())
+-        for path, fd in p.get_open_files():
+-            if path == fileobj.name or fd == fileobj.fileno():
+-                break
+-        else:
+-            self.fail("no file found; files=%s" % repr(p.get_open_files()))
+-        self.assertEqual(path, fileobj.name)
+-        if WINDOWS:
+-            self.assertEqual(fd, -1)
+-        else:
+-            self.assertEqual(fd, fileobj.fileno())
+-        # test positions
+-        ntuple = p.get_open_files()[0]
+-        self.assertEqual(ntuple[0], ntuple.path)
+-        self.assertEqual(ntuple[1], ntuple.fd)
+-        # test file is gone
+-        fileobj.close()
+-        self.assertTrue(fileobj.name not in p.get_open_files())
+-
+-    def test_get_connections(self):
+-        arg = "import socket, time;" \
+-              "s = socket.socket();" \
+-              "s.bind(('127.0.0.1', 0));" \
+-              "s.listen(1);" \
+-              "conn, addr = s.accept();" \
+-              "time.sleep(100);"
+-        sproc = get_test_subprocess([PYTHON, "-c", arg])
+-        p = psutil.Process(sproc.pid)
+-        for x in range(100):
+-            cons = p.get_connections()
+-            if cons:
+-                break
+-            time.sleep(.01)
+-        self.assertEqual(len(cons), 1)
+-        con = cons[0]
+-        self.assertEqual(con.family, socket.AF_INET)
+-        self.assertEqual(con.type, socket.SOCK_STREAM)
+-        self.assertEqual(con.status, "LISTEN")
+-        ip, port = con.local_address
+-        self.assertEqual(ip, '127.0.0.1')
+-        self.assertEqual(con.remote_address, ())
+-        if WINDOWS:
+-            self.assertEqual(con.fd, -1)
+-        else:
+-            assert con.fd > 0, con
+-        # test positions
+-        self.assertEqual(con[0], con.fd)
+-        self.assertEqual(con[1], con.family)
+-        self.assertEqual(con[2], con.type)
+-        self.assertEqual(con[3], con.local_address)
+-        self.assertEqual(con[4], con.remote_address)
+-        self.assertEqual(con[5], con.status)
+-        # test kind arg
+-        self.assertRaises(ValueError, p.get_connections, 'foo')
+-
+-    @skipUnless(supports_ipv6())
+-    def test_get_connections_ipv6(self):
+-        s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+-        s.bind(('::1', 0))
+-        s.listen(1)
+-        cons = psutil.Process(os.getpid()).get_connections()
+-        s.close()
+-        self.assertEqual(len(cons), 1)
+-        self.assertEqual(cons[0].local_address[0], '::1')
+-
+-    @skipUnless(hasattr(socket, 'AF_UNIX'))
+-    def test_get_connections_unix(self):
+-        # tcp
+-        safe_remove(TESTFN)
+-        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+-        sock.bind(TESTFN)
+-        conn = psutil.Process(os.getpid()).get_connections(kind='unix')[0]
+-        self.assertEqual(conn.fd, sock.fileno())
+-        self.assertEqual(conn.family, socket.AF_UNIX)
+-        self.assertEqual(conn.type, socket.SOCK_STREAM)
+-        self.assertEqual(conn.local_address, TESTFN)
+-        self.assertTrue(not conn.remote_address)
+-        self.assertTrue(not conn.status)
+-        sock.close()
+-        # udp
+-        safe_remove(TESTFN)
+-        sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+-        sock.bind(TESTFN)
+-        conn = psutil.Process(os.getpid()).get_connections(kind='unix')[0]
+-        self.assertEqual(conn.type, socket.SOCK_DGRAM)
+-        sock.close()
+-
+-    @skipUnless(hasattr(socket, "fromfd") and not WINDOWS)
+-    def test_connection_fromfd(self):
+-        sock = socket.socket()
+-        sock.bind(('localhost', 0))
+-        sock.listen(1)
+-        p = psutil.Process(os.getpid())
+-        for conn in p.get_connections():
+-            if conn.fd == sock.fileno():
+-                break
+-        else:
+-            sock.close()
+-            self.fail("couldn't find socket fd")
+-        dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
+-        try:
+-            self.assertEqual(dupsock.getsockname(), conn.local_address)
+-            self.assertNotEqual(sock.fileno(), dupsock.fileno())
+-        finally:
+-            sock.close()
+-            dupsock.close()
+-
+-    def test_get_connections_all(self):
+-        tcp_template = "import socket;" \
+-                       "s = socket.socket($family, socket.SOCK_STREAM);" \
+-                       "s.bind(('$addr', 0));" \
+-                       "s.listen(1);" \
+-                       "conn, addr = s.accept();"
+-
+-        udp_template = "import socket, time;" \
+-                       "s = socket.socket($family, socket.SOCK_DGRAM);" \
+-                       "s.bind(('$addr', 0));" \
+-                       "time.sleep(100);"
++        with open(TESTFN, 'w') as fileobj:
++            p = psutil.Process()
++            for path, fd in p.open_files():
++                if path == fileobj.name or fd == fileobj.fileno():
++                    break
++            else:
++                self.fail("no file found; files=%s" % repr(p.open_files()))
++            self.assertEqual(path, fileobj.name)
++            if WINDOWS:
++                self.assertEqual(fd, -1)
++            else:
++                self.assertEqual(fd, fileobj.fileno())
++            # test positions
++            ntuple = p.open_files()[0]
++            self.assertEqual(ntuple[0], ntuple.path)
++            self.assertEqual(ntuple[1], ntuple.fd)
++            # test file is gone
++            self.assertTrue(fileobj.name not in p.open_files())
++
++    def compare_proc_sys_cons(self, pid, proc_cons):
++        from psutil._common import pconn
++        sys_cons = []
++        for c in psutil.net_connections(kind='all'):
++            if c.pid == pid:
++                sys_cons.append(pconn(*c[:-1]))
++        if BSD:
++            # on BSD all fds are set to -1
++            proc_cons = [pconn(*[-1] + list(x[1:])) for x in proc_cons]
++        self.assertEqual(sorted(proc_cons), sorted(sys_cons))
++
++    @skip_on_access_denied(only_if=OSX)
++    def test_connections(self):
++        def check_conn(proc, conn, family, type, laddr, raddr, status, kinds):
++            all_kinds = ("all", "inet", "inet4", "inet6", "tcp", "tcp4",
++                         "tcp6", "udp", "udp4", "udp6")
++            check_connection_ntuple(conn)
++            self.assertEqual(conn.family, family)
++            self.assertEqual(conn.type, type)
++            self.assertEqual(conn.laddr, laddr)
++            self.assertEqual(conn.raddr, raddr)
++            self.assertEqual(conn.status, status)
++            for kind in all_kinds:
++                cons = proc.connections(kind=kind)
++                if kind in kinds:
++                    self.assertNotEqual(cons, [])
++                else:
++                    self.assertEqual(cons, [])
++            # compare against system-wide connections
++            # XXX Solaris can't retrieve system-wide UNIX
++            # sockets.
++            if not SUNOS:
++                self.compare_proc_sys_cons(proc.pid, [conn])
++
++        tcp_template = textwrap.dedent("""
++            import socket, time
++            s = socket.socket($family, socket.SOCK_STREAM)
++            s.bind(('$addr', 0))
++            s.listen(1)
++            with open('$testfn', 'w') as f:
++                f.write(str(s.getsockname()[:2]))
++            time.sleep(60)
++        """)
++
++        udp_template = textwrap.dedent("""
++            import socket, time
++            s = socket.socket($family, socket.SOCK_DGRAM)
++            s.bind(('$addr', 0))
++            with open('$testfn', 'w') as f:
++                f.write(str(s.getsockname()[:2]))
++            time.sleep(60)
++        """)
+ 
+         from string import Template
+-        tcp4_template = Template(tcp_template).substitute(family=socket.AF_INET,
+-                                                          addr="127.0.0.1")
+-        udp4_template = Template(udp_template).substitute(family=socket.AF_INET,
+-                                                          addr="127.0.0.1")
+-        tcp6_template = Template(tcp_template).substitute(family=socket.AF_INET6,
+-                                                          addr="::1")
+-        udp6_template = Template(udp_template).substitute(family=socket.AF_INET6,
+-                                                          addr="::1")
++        testfile = os.path.basename(TESTFN)
++        tcp4_template = Template(tcp_template).substitute(
++            family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
++        udp4_template = Template(udp_template).substitute(
++            family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
++        tcp6_template = Template(tcp_template).substitute(
++            family=int(AF_INET6), addr="::1", testfn=testfile)
++        udp6_template = Template(udp_template).substitute(
++            family=int(AF_INET6), addr="::1", testfn=testfile)
+ 
+         # launch various subprocess instantiating a socket of various
+         # families and types to enrich psutil results
+-        tcp4_proc = get_test_subprocess([PYTHON, "-c", tcp4_template])
+-        udp4_proc = get_test_subprocess([PYTHON, "-c", udp4_template])
++        tcp4_proc = pyrun(tcp4_template)
++        tcp4_addr = eval(wait_for_file(testfile))
++        udp4_proc = pyrun(udp4_template)
++        udp4_addr = eval(wait_for_file(testfile))
+         if supports_ipv6():
+-            tcp6_proc = get_test_subprocess([PYTHON, "-c", tcp6_template])
+-            udp6_proc = get_test_subprocess([PYTHON, "-c", udp6_template])
++            tcp6_proc = pyrun(tcp6_template)
++            tcp6_addr = eval(wait_for_file(testfile))
++            udp6_proc = pyrun(udp6_template)
++            udp6_addr = eval(wait_for_file(testfile))
+         else:
+             tcp6_proc = None
+             udp6_proc = None
++            tcp6_addr = None
++            udp6_addr = None
+ 
+-        # check matches against subprocesses just created
+-        all_kinds = ("all", "inet", "inet4", "inet6", "tcp", "tcp4", "tcp6",
+-                     "udp", "udp4", "udp6")
+-        for p in psutil.Process(os.getpid()).get_children():
+-            for conn in p.get_connections():
++        for p in psutil.Process().children():
++            cons = p.connections()
++            self.assertEqual(len(cons), 1)
++            for conn in cons:
+                 # TCP v4
+                 if p.pid == tcp4_proc.pid:
+-                    self.assertEqual(conn.family, socket.AF_INET)
+-                    self.assertEqual(conn.type, socket.SOCK_STREAM)
+-                    self.assertEqual(conn.local_address[0], "127.0.0.1")
+-                    self.assertEqual(conn.remote_address, ())
+-                    self.assertEqual(conn.status, "LISTEN")
+-                    for kind in all_kinds:
+-                        cons = p.get_connections(kind=kind)
+-                        if kind in ("all", "inet", "inet4", "tcp", "tcp4"):
+-                            assert cons != [], cons
+-                        else:
+-                            self.assertEqual(cons, [], cons)
++                    check_conn(p, conn, AF_INET, SOCK_STREAM, tcp4_addr, (),
++                               psutil.CONN_LISTEN,
++                               ("all", "inet", "inet4", "tcp", "tcp4"))
+                 # UDP v4
+                 elif p.pid == udp4_proc.pid:
+-                    self.assertEqual(conn.family, socket.AF_INET)
+-                    self.assertEqual(conn.type, socket.SOCK_DGRAM)
+-                    self.assertEqual(conn.local_address[0], "127.0.0.1")
+-                    self.assertEqual(conn.remote_address, ())
+-                    self.assertEqual(conn.status, "")
+-                    for kind in all_kinds:
+-                        cons = p.get_connections(kind=kind)
+-                        if kind in ("all", "inet", "inet4", "udp", "udp4"):
+-                            assert cons != [], cons
+-                        else:
+-                            self.assertEqual(cons, [], cons)
++                    check_conn(p, conn, AF_INET, SOCK_DGRAM, udp4_addr, (),
++                               psutil.CONN_NONE,
++                               ("all", "inet", "inet4", "udp", "udp4"))
+                 # TCP v6
+                 elif p.pid == getattr(tcp6_proc, "pid", None):
+-                    self.assertEqual(conn.family, socket.AF_INET6)
+-                    self.assertEqual(conn.type, socket.SOCK_STREAM)
+-                    self.assertIn(conn.local_address[0], ("::", "::1"))
+-                    self.assertEqual(conn.remote_address, ())
+-                    self.assertEqual(conn.status, "LISTEN")
+-                    for kind in all_kinds:
+-                        cons = p.get_connections(kind=kind)
+-                        if kind in ("all", "inet", "inet6", "tcp", "tcp6"):
+-                            assert cons != [], cons
+-                        else:
+-                            self.assertEqual(cons, [], cons)
++                    check_conn(p, conn, AF_INET6, SOCK_STREAM, tcp6_addr, (),
++                               psutil.CONN_LISTEN,
++                               ("all", "inet", "inet6", "tcp", "tcp6"))
+                 # UDP v6
+                 elif p.pid == getattr(udp6_proc, "pid", None):
+-                    self.assertEqual(conn.family, socket.AF_INET6)
+-                    self.assertEqual(conn.type, socket.SOCK_DGRAM)
+-                    self.assertIn(conn.local_address[0], ("::", "::1"))
+-                    self.assertEqual(conn.remote_address, ())
+-                    self.assertEqual(conn.status, "")
+-                    for kind in all_kinds:
+-                        cons = p.get_connections(kind=kind)
+-                        if kind in ("all", "inet", "inet6", "udp", "udp6"):
+-                            assert cons != [], cons
+-                        else:
+-                            self.assertEqual(cons, [], cons)
++                    check_conn(p, conn, AF_INET6, SOCK_DGRAM, udp6_addr, (),
++                               psutil.CONN_NONE,
++                               ("all", "inet", "inet6", "udp", "udp6"))
++
++    @unittest.skipUnless(hasattr(socket, 'AF_UNIX'),
++                         'AF_UNIX is not supported')
++    @skip_on_access_denied(only_if=OSX)
++    def test_connections_unix(self):
++        def check(type):
++            safe_remove(TESTFN)
++            sock = socket.socket(AF_UNIX, type)
++            with contextlib.closing(sock):
++                sock.bind(TESTFN)
++                cons = psutil.Process().connections(kind='unix')
++                conn = cons[0]
++                check_connection_ntuple(conn)
++                if conn.fd != -1:  # != sunos and windows
++                    self.assertEqual(conn.fd, sock.fileno())
++                self.assertEqual(conn.family, AF_UNIX)
++                self.assertEqual(conn.type, type)
++                self.assertEqual(conn.laddr, TESTFN)
++                if not SUNOS:
++                    # XXX Solaris can't retrieve system-wide UNIX
++                    # sockets.
++                    self.compare_proc_sys_cons(os.getpid(), cons)
++
++        check(SOCK_STREAM)
++        check(SOCK_DGRAM)
++
++    @unittest.skipUnless(hasattr(socket, "fromfd"),
++                         'socket.fromfd() is not availble')
++    @unittest.skipIf(WINDOWS or SUNOS,
++                     'connection fd not available on this platform')
++    def test_connection_fromfd(self):
++        with contextlib.closing(socket.socket()) as sock:
++            sock.bind(('localhost', 0))
++            sock.listen(1)
++            p = psutil.Process()
++            for conn in p.connections():
++                if conn.fd == sock.fileno():
++                    break
++            else:
++                self.fail("couldn't find socket fd")
++            dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
++            with contextlib.closing(dupsock):
++                self.assertEqual(dupsock.getsockname(), conn.laddr)
++                self.assertNotEqual(sock.fileno(), dupsock.fileno())
++
++    def test_connection_constants(self):
++        ints = []
++        strs = []
++        for name in dir(psutil):
++            if name.startswith('CONN_'):
++                num = getattr(psutil, name)
++                str_ = str(num)
++                assert str_.isupper(), str_
++                assert str_ not in strs, str_
++                assert num not in ints, num
++                ints.append(num)
++                strs.append(str_)
++        if SUNOS:
++            psutil.CONN_IDLE
++            psutil.CONN_BOUND
++        if WINDOWS:
++            psutil.CONN_DELETE_TCB
+ 
+-    @skipUnless(POSIX)
+-    def test_get_num_fds(self):
+-        p = psutil.Process(os.getpid())
+-        start = p.get_num_fds()
++    @unittest.skipUnless(POSIX, 'posix only')
++    def test_num_fds(self):
++        p = psutil.Process()
++        start = p.num_fds()
+         file = open(TESTFN, 'w')
+-        self.assertEqual(p.get_num_fds(), start + 1)
++        self.addCleanup(file.close)
++        self.assertEqual(p.num_fds(), start + 1)
+         sock = socket.socket()
+-        self.assertEqual(p.get_num_fds(), start + 2)
++        self.addCleanup(sock.close)
++        self.assertEqual(p.num_fds(), start + 2)
+         file.close()
+         sock.close()
+-        self.assertEqual(p.get_num_fds(), start)
++        self.assertEqual(p.num_fds(), start)
+ 
+-    def test_get_num_ctx_switches(self):
+-        p = psutil.Process(os.getpid())
+-        before = sum(p.get_num_ctx_switches())
++    @skip_on_not_implemented(only_if=LINUX)
++    def test_num_ctx_switches(self):
++        p = psutil.Process()
++        before = sum(p.num_ctx_switches())
+         for x in range(500000):
+-            after = sum(p.get_num_ctx_switches())
++            after = sum(p.num_ctx_switches())
+             if after > before:
+                 return
+         self.fail("num ctx switches still the same after 50.000 iterations")
+@@ -1444,61 +1943,60 @@
+         this_parent = os.getpid()
+         sproc = get_test_subprocess()
+         p = psutil.Process(sproc.pid)
+-        self.assertEqual(p.ppid, this_parent)
+-        self.assertEqual(p.parent.pid, this_parent)
++        self.assertEqual(p.ppid(), this_parent)
++        self.assertEqual(p.parent().pid, this_parent)
+         # no other process is supposed to have us as parent
+         for p in psutil.process_iter():
+             if p.pid == sproc.pid:
+                 continue
+-            self.assertTrue(p.ppid != this_parent)
++            self.assertTrue(p.ppid() != this_parent)
+ 
+-    def test_get_children(self):
+-        p = psutil.Process(os.getpid())
+-        self.assertEqual(p.get_children(), [])
+-        self.assertEqual(p.get_children(recursive=True), [])
++    def test_children(self):
++        p = psutil.Process()
++        self.assertEqual(p.children(), [])
++        self.assertEqual(p.children(recursive=True), [])
+         sproc = get_test_subprocess()
+-        children1 = p.get_children()
+-        children2 = p.get_children(recursive=True)
++        children1 = p.children()
++        children2 = p.children(recursive=True)
+         for children in (children1, children2):
+             self.assertEqual(len(children), 1)
+             self.assertEqual(children[0].pid, sproc.pid)
+-            self.assertEqual(children[0].ppid, os.getpid())
++            self.assertEqual(children[0].ppid(), os.getpid())
+ 
+-    def test_get_children_recursive(self):
++    def test_children_recursive(self):
+         # here we create a subprocess which creates another one as in:
+         # A (parent) -> B (child) -> C (grandchild)
+-        s =  "import subprocess, os, sys, time;"
++        s = "import subprocess, os, sys, time;"
+         s += "PYTHON = os.path.realpath(sys.executable);"
+-        s += "cmd = [PYTHON, '-c', 'import time; time.sleep(3600);'];"
++        s += "cmd = [PYTHON, '-c', 'import time; time.sleep(60);'];"
+         s += "subprocess.Popen(cmd);"
+-        s += "time.sleep(3600);"
++        s += "time.sleep(60);"
+         get_test_subprocess(cmd=[PYTHON, "-c", s])
+-        p = psutil.Process(os.getpid())
+-        self.assertEqual(len(p.get_children(recursive=False)), 1)
++        p = psutil.Process()
++        self.assertEqual(len(p.children(recursive=False)), 1)
+         # give the grandchild some time to start
+         stop_at = time.time() + 1.5
+         while time.time() < stop_at:
+-            children = p.get_children(recursive=True)
++            children = p.children(recursive=True)
+             if len(children) > 1:
+                 break
+         self.assertEqual(len(children), 2)
+-        self.assertEqual(children[0].ppid, os.getpid())
+-        self.assertEqual(children[1].ppid, children[0].pid)
++        self.assertEqual(children[0].ppid(), os.getpid())
++        self.assertEqual(children[1].ppid(), children[0].pid)
+ 
+-    def test_get_children_duplicates(self):
++    def test_children_duplicates(self):
+         # find the process which has the highest number of children
+-        from psutil._compat import defaultdict
+-        table = defaultdict(int)
++        table = collections.defaultdict(int)
+         for p in psutil.process_iter():
+             try:
+-                table[p.ppid] += 1
++                table[p.ppid()] += 1
+             except psutil.Error:
+                 pass
+         # this is the one, now let's make sure there are no duplicates
+         pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
+         p = psutil.Process(pid)
+         try:
+-            c = p.get_children(recursive=True)
++            c = p.children(recursive=True)
+         except psutil.AccessDenied:  # windows
+             pass
+         else:
+@@ -1509,156 +2007,220 @@
+         p = psutil.Process(sproc.pid)
+         p.suspend()
+         for x in range(100):
+-            if p.status == psutil.STATUS_STOPPED:
++            if p.status() == psutil.STATUS_STOPPED:
+                 break
+             time.sleep(0.01)
+-        self.assertEqual(str(p.status), "stopped")
+         p.resume()
+-        assert p.status != psutil.STATUS_STOPPED, p.status
++        self.assertNotEqual(p.status(), psutil.STATUS_STOPPED)
+ 
+     def test_invalid_pid(self):
+         self.assertRaises(TypeError, psutil.Process, "1")
+-        self.assertRaises(TypeError, psutil.Process, None)
+         self.assertRaises(ValueError, psutil.Process, -1)
+ 
+     def test_as_dict(self):
+-        sproc = get_test_subprocess()
+-        p = psutil.Process(sproc.pid)
+-        d = p.as_dict()
+-        try:
+-            import json
+-        except ImportError:
+-            pass
+-        else:
+-            # dict is supposed to be hashable
+-            json.dumps(d)
+-        #
++        p = psutil.Process()
+         d = p.as_dict(attrs=['exe', 'name'])
+         self.assertEqual(sorted(d.keys()), ['exe', 'name'])
+-        #
+-        p = psutil.Process(min(psutil.get_pid_list()))
+-        d = p.as_dict(attrs=['get_connections'], ad_value='foo')
++
++        p = psutil.Process(min(psutil.pids()))
++        d = p.as_dict(attrs=['connections'], ad_value='foo')
+         if not isinstance(d['connections'], list):
+             self.assertEqual(d['connections'], 'foo')
+ 
+-    def test_zombie_process(self):
++    def test_halfway_terminated_process(self):
+         # Test that NoSuchProcess exception gets raised in case the
+         # process dies after we create the Process object.
+         # Example:
+         #  >>> proc = Process(1234)
+-        #  >>> time.sleep(5)  # time-consuming task, process dies in meantime
+-        #  >>> proc.name
++        # >>> time.sleep(2)  # time-consuming task, process dies in meantime
++        #  >>> proc.name()
+         # Refers to Issue #15
+         sproc = get_test_subprocess()
+         p = psutil.Process(sproc.pid)
+         p.kill()
+         p.wait()
+ 
++        excluded_names = ['pid', 'is_running', 'wait', 'create_time']
++        if LINUX and not RLIMIT_SUPPORT:
++            excluded_names.append('rlimit')
+         for name in dir(p):
+-            if name.startswith('_')\
+-            or name in ('pid', 'send_signal', 'is_running', 'set_ionice',
+-                        'wait', 'set_cpu_affinity', 'create_time', 'set_nice',
+-                        'nice'):
++            if (name.startswith('_') or
++                    name in excluded_names):
+                 continue
+             try:
+                 meth = getattr(p, name)
+-                if callable(meth):
++                # get/set methods
++                if name == 'nice':
++                    if POSIX:
++                        meth(1)
++                    else:
++                        meth(psutil.NORMAL_PRIORITY_CLASS)
++                elif name == 'ionice':
++                    meth()
++                    meth(2)
++                elif name == 'rlimit':
++                    meth(psutil.RLIMIT_NOFILE)
++                    meth(psutil.RLIMIT_NOFILE, (5, 5))
++                elif name == 'cpu_affinity':
++                    meth()
++                    meth([0])
++                elif name == 'send_signal':
++                    meth(signal.SIGTERM)
++                else:
+                     meth()
++            except psutil.ZombieProcess:
++                self.fail("ZombieProcess for %r was not supposed to happen" %
++                          name)
+             except psutil.NoSuchProcess:
+                 pass
++            except NotImplementedError:
++                pass
+             else:
+                 self.fail("NoSuchProcess exception not raised for %r" % name)
+ 
+-        # other methods
+-        try:
+-            if os.name == 'posix':
+-                p.set_nice(1)
+-            else:
+-                p.set_nice(psutil.NORMAL_PRIORITY_CLASS)
+-        except psutil.NoSuchProcess:
+-            pass
+-        else:
+-            self.fail("exception not raised")
+-        if hasattr(p, 'set_ionice'):
+-            self.assertRaises(psutil.NoSuchProcess, p.set_ionice, 2)
+-        self.assertRaises(psutil.NoSuchProcess, p.send_signal, signal.SIGTERM)
+-        self.assertRaises(psutil.NoSuchProcess, p.set_nice, 0)
+         self.assertFalse(p.is_running())
+-        if hasattr(p, "set_cpu_affinity"):
+-            self.assertRaises(psutil.NoSuchProcess, p.set_cpu_affinity, [0])
+ 
+-    def test__str__(self):
+-        sproc = get_test_subprocess()
+-        p = psutil.Process(sproc.pid)
+-        self.assertIn(str(sproc.pid), str(p))
+-        # python shows up as 'Python' in cmdline on OS X so test fails on OS X
+-        if not OSX:
+-            self.assertIn(os.path.basename(PYTHON), str(p))
+-        sproc = get_test_subprocess()
+-        p = psutil.Process(sproc.pid)
+-        p.kill()
+-        p.wait()
+-        self.assertIn(str(sproc.pid), str(p))
+-        self.assertIn("terminated", str(p))
++    @unittest.skipUnless(POSIX, 'posix only')
++    def test_zombie_process(self):
++        def succeed_or_zombie_p_exc(fun, *args, **kwargs):
++            try:
++                fun(*args, **kwargs)
++            except (psutil.ZombieProcess, psutil.AccessDenied):
++                pass
++
++        # Note: in this test we'll be creating two sub processes.
++        # Both of them are supposed to be freed / killed by
++        # reap_children() as they are attributable to 'us'
++        # (os.getpid()) via children(recursive=True).
++        src = textwrap.dedent("""\
++        import os, sys, time, socket, contextlib
++        child_pid = os.fork()
++        if child_pid > 0:
++            time.sleep(3000)
++        else:
++            # this is the zombie process
++            s = socket.socket(socket.AF_UNIX)
++            with contextlib.closing(s):
++                s.connect('%s')
++                if sys.version_info < (3, ):
++                    pid = str(os.getpid())
++                else:
++                    pid = bytes(str(os.getpid()), 'ascii')
++                s.sendall(pid)
++        """ % TESTFN)
++        with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
++            try:
++                sock.settimeout(GLOBAL_TIMEOUT)
++                sock.bind(TESTFN)
++                sock.listen(1)
++                pyrun(src)
++                conn, _ = sock.accept()
++                select.select([conn.fileno()], [], [], GLOBAL_TIMEOUT)
++                zpid = int(conn.recv(1024))
++                zproc = psutil.Process(zpid)
++                call_until(lambda: zproc.status(),
++                           "ret == psutil.STATUS_ZOMBIE")
++                # A zombie process should always be instantiable
++                zproc = psutil.Process(zpid)
++                # ...and at least its status always be querable
++                self.assertEqual(zproc.status(), psutil.STATUS_ZOMBIE)
++                # ...and it should be considered 'running'
++                self.assertTrue(zproc.is_running())
++                # ...and as_dict() shouldn't crash
++                zproc.as_dict()
++                if hasattr(zproc, "rlimit"):
++                    succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE)
++                    succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE,
++                                            (5, 5))
++                # set methods
++                succeed_or_zombie_p_exc(zproc.parent)
++                if hasattr(zproc, 'cpu_affinity'):
++                    succeed_or_zombie_p_exc(zproc.cpu_affinity, [0])
++                succeed_or_zombie_p_exc(zproc.nice, 0)
++                if hasattr(zproc, 'ionice'):
++                    if LINUX:
++                        succeed_or_zombie_p_exc(zproc.ionice, 2, 0)
++                    else:
++                        succeed_or_zombie_p_exc(zproc.ionice, 0)  # Windows
++                if hasattr(zproc, 'rlimit'):
++                    succeed_or_zombie_p_exc(zproc.rlimit,
++                                            psutil.RLIMIT_NOFILE, (5, 5))
++                succeed_or_zombie_p_exc(zproc.suspend)
++                succeed_or_zombie_p_exc(zproc.resume)
++                succeed_or_zombie_p_exc(zproc.terminate)
++                succeed_or_zombie_p_exc(zproc.kill)
++
++                # ...its parent should 'see' it
++                # edit: not true on BSD and OSX
++                # descendants = [x.pid for x in psutil.Process().children(
++                #                recursive=True)]
++                # self.assertIn(zpid, descendants)
++                # XXX should we also assume ppid be usable?  Note: this
++                # would be an important use case as the only way to get
++                # rid of a zombie is to kill its parent.
++                # self.assertEqual(zpid.ppid(), os.getpid())
++                # ...and all other APIs should be able to deal with it
++                self.assertTrue(psutil.pid_exists(zpid))
++                self.assertIn(zpid, psutil.pids())
++                self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
++                psutil._pmap = {}
++                self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
++            finally:
++                reap_children(search_all=True)
+ 
+-    @skipIf(LINUX)
+     def test_pid_0(self):
+         # Process(0) is supposed to work on all platforms except Linux
++        if 0 not in psutil.pids():
++            self.assertRaises(psutil.NoSuchProcess, psutil.Process, 0)
++            return
++
+         p = psutil.Process(0)
+-        self.assertTrue(p.name)
++        self.assertTrue(p.name())
++
++        if POSIX:
++            try:
++                self.assertEqual(p.uids().real, 0)
++                self.assertEqual(p.gids().real, 0)
++            except psutil.AccessDenied:
++                pass
+ 
+-        if os.name == 'posix':
+-            self.assertEqual(p.uids.real, 0)
+-            self.assertEqual(p.gids.real, 0)
+-
+-        self.assertIn(p.ppid, (0, 1))
+-        #self.assertEqual(p.exe, "")
+-        self.assertEqual(p.cmdline, [])
++        self.assertIn(p.ppid(), (0, 1))
++        # self.assertEqual(p.exe(), "")
++        p.cmdline()
+         try:
+-            p.get_num_threads()
++            p.num_threads()
+         except psutil.AccessDenied:
+             pass
+ 
+         try:
+-            p.get_memory_info()
++            p.memory_info()
+         except psutil.AccessDenied:
+             pass
+ 
+         # username property
+-        if POSIX:
+-            self.assertEqual(p.username, 'root')
+-        elif WINDOWS:
+-            self.assertEqual(p.username, 'NT AUTHORITY\\SYSTEM')
+-        else:
+-            p.username
++        try:
++            if POSIX:
++                self.assertEqual(p.username(), 'root')
++            elif WINDOWS:
++                self.assertEqual(p.username(), 'NT AUTHORITY\\SYSTEM')
++            else:
++                p.username()
++        except psutil.AccessDenied:
++            pass
+ 
+-        self.assertIn(0, psutil.get_pid_list())
++        self.assertIn(0, psutil.pids())
+         self.assertTrue(psutil.pid_exists(0))
+ 
+-    def test__all__(self):
+-        for name in dir(psutil):
+-            if name in ('callable', 'defaultdict', 'error', 'namedtuple'):
+-                continue
+-            if not name.startswith('_'):
+-                try:
+-                    __import__(name)
+-                except ImportError:
+-                    if name not in psutil.__all__:
+-                        fun = getattr(psutil, name)
+-                        if fun is None:
+-                            continue
+-                        if 'deprecated' not in fun.__doc__.lower():
+-                            self.fail('%r not in psutil.__all__' % name)
+-
+     def test_Popen(self):
+         # Popen class test
+         # XXX this test causes a ResourceWarning on Python 3 because
+         # psutil.__subproc instance doesn't get propertly freed.
+         # Not sure what to do though.
+-        cmd = [PYTHON, "-c", "import time; time.sleep(3600);"]
+-        proc = psutil.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
++        cmd = [PYTHON, "-c", "import time; time.sleep(60);"]
++        proc = psutil.Popen(cmd, stdout=subprocess.PIPE,
++                            stderr=subprocess.PIPE)
+         try:
+-            proc.name
++            proc.name()
+             proc.stdin
+             self.assertTrue(hasattr(proc, 'name'))
+             self.assertTrue(hasattr(proc, 'stdin'))
+@@ -1666,18 +2228,17 @@
+         finally:
+             proc.kill()
+             proc.wait()
++            self.assertIsNotNone(proc.returncode)
+ 
+ 
+-class TestFetchAllProcesses(unittest.TestCase):
+-    # Iterates over all running processes and performs some sanity
+-    # checks against Process API's returned values.
++# ===================================================================
++# --- Featch all processes test
++# ===================================================================
+ 
+-    # Python 2.4 compatibility
+-    if not hasattr(unittest.TestCase, "assertIn"):
+-        def assertIn(self, member, container, msg=None):
+-            if member not in container:
+-                self.fail(msg or \
+-                        '%s not found in %s' % (repr(member), repr(container)))
++class TestFetchAllProcesses(unittest.TestCase):
++    """Test which iterates over all running processes and performs
++    some sanity checks against Process API's returned values.
++    """
+ 
+     def setUp(self):
+         if POSIX:
+@@ -1688,15 +2249,15 @@
+ 
+     def test_fetch_all(self):
+         valid_procs = 0
+-        excluded_names = ['send_signal', 'suspend', 'resume', 'terminate',
+-                          'kill', 'wait', 'as_dict', 'get_cpu_percent', 'nice',
+-                          'parent', 'get_children', 'pid']
++        excluded_names = set([
++            'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
++            'as_dict', 'cpu_percent', 'parent', 'children', 'pid'])
++        if LINUX and not RLIMIT_SUPPORT:
++            excluded_names.add('rlimit')
+         attrs = []
+         for name in dir(psutil.Process):
+             if name.startswith("_"):
+                 continue
+-            if name.startswith("set_"):
+-                continue
+             if name in excluded_names:
+                 continue
+             attrs.append(name)
+@@ -1708,26 +2269,25 @@
+                 ret = default
+                 try:
+                     try:
++                        args = ()
+                         attr = getattr(p, name, None)
+                         if attr is not None and callable(attr):
+-                            ret = attr()
++                            if name == 'rlimit':
++                                args = (psutil.RLIMIT_NOFILE,)
++                            ret = attr(*args)
+                         else:
+                             ret = attr
+                         valid_procs += 1
+-                    except (psutil.NoSuchProcess, psutil.AccessDenied):
+-                        err = sys.exc_info()[1]
+-                        if isinstance(err, psutil.NoSuchProcess):
+-                            if psutil.pid_exists(p.pid):
+-                                # XXX race condition; we probably need
+-                                # to try figuring out the process
+-                                # identity before failing
+-                                self.fail("PID still exists but fun raised " \
+-                                          "NoSuchProcess")
++                    except NotImplementedError:
++                        msg = "%r was skipped because not implemented" % (
++                            self.__class__.__name__ + '.test_' + name)
++                        warn(msg)
++                    except (psutil.NoSuchProcess, psutil.AccessDenied) as err:
+                         self.assertEqual(err.pid, p.pid)
+                         if err.name:
+                             # make sure exception's name attr is set
+                             # with the actual process name
+-                            self.assertEqual(err.name, p.name)
++                            self.assertEqual(err.name, p.name())
+                         self.assertTrue(str(err))
+                         self.assertTrue(err.msg)
+                     else:
+@@ -1735,8 +2295,7 @@
+                             assert ret, ret
+                         meth = getattr(self, name)
+                         meth(ret)
+-                except Exception:
+-                    err = sys.exc_info()[1]
++                except Exception as err:
+                     s = '\n' + '=' * 70 + '\n'
+                     s += "FAIL: test_%s (proc=%s" % (name, p)
+                     if ret != default:
+@@ -1744,7 +2303,7 @@
+                     s += ')\n'
+                     s += '-' * 70
+                     s += "\n%s" % traceback.format_exc()
+-                    s =  "\n".join((" " * 4) + i for i in s.splitlines())
++                    s = "\n".join((" " * 4) + i for i in s.splitlines())
+                     failures.append(s)
+                     break
+ 
+@@ -1760,14 +2319,13 @@
+ 
+     def exe(self, ret):
+         if not ret:
+-            assert ret == ''
++            self.assertEqual(ret, '')
+         else:
+             assert os.path.isabs(ret), ret
+             # Note: os.stat() may return False even if the file is there
+             # hence we skip the test, see:
+             # http://stackoverflow.com/questions/3112546/os-path-exists-lies
+-            if POSIX:
+-                assert os.path.isfile(ret), ret
++            if POSIX and os.path.isfile(ret):
+                 if hasattr(os, 'access') and hasattr(os, "X_OK"):
+                     # XXX may fail on OSX
+                     self.assertTrue(os.access(ret, os.X_OK))
+@@ -1776,13 +2334,13 @@
+         self.assertTrue(ret >= 0)
+ 
+     def name(self, ret):
+-        self.assertTrue(isinstance(ret, str))
++        self.assertIsInstance(ret, (str, unicode))
+         self.assertTrue(ret)
+ 
+     def create_time(self, ret):
+         self.assertTrue(ret > 0)
+-        if not WINDOWS:
+-            assert ret >= psutil.BOOT_TIME, (ret, psutil.BOOT_TIME)
++        # this can't be taken for granted on all platforms
++        # self.assertGreaterEqual(ret, psutil.boot_time())
+         # make sure returned value can be pretty printed
+         # with strftime
+         time.strftime("%Y %m %d %H:%M:%S", time.localtime(ret))
+@@ -1797,23 +2355,24 @@
+         # gid == 30 (nodoby); not sure why.
+         for gid in ret:
+             self.assertTrue(gid >= 0)
+-            #self.assertIn(uid, self.gids)
++            # self.assertIn(uid, self.gids
+ 
+     def username(self, ret):
+         self.assertTrue(ret)
+-        if os.name == 'posix':
++        if POSIX:
+             self.assertIn(ret, self._usernames)
+ 
+     def status(self, ret):
+-        self.assertTrue(ret >= 0)
+-        self.assertTrue(str(ret) != '?')
++        self.assertTrue(ret != "")
++        self.assertTrue(ret != '?')
++        self.assertIn(ret, VALID_PROC_STATUSES)
+ 
+-    def get_io_counters(self, ret):
++    def io_counters(self, ret):
+         for field in ret:
+             if field != -1:
+                 self.assertTrue(field >= 0)
+ 
+-    def get_ionice(self, ret):
++    def ionice(self, ret):
+         if LINUX:
+             self.assertTrue(ret.ioclass >= 0)
+             self.assertTrue(ret.value >= 0)
+@@ -1821,24 +2380,24 @@
+             self.assertTrue(ret >= 0)
+             self.assertIn(ret, (0, 1, 2))
+ 
+-    def get_num_threads(self, ret):
++    def num_threads(self, ret):
+         self.assertTrue(ret >= 1)
+ 
+-    def get_threads(self, ret):
++    def threads(self, ret):
+         for t in ret:
+             self.assertTrue(t.id >= 0)
+             self.assertTrue(t.user_time >= 0)
+             self.assertTrue(t.system_time >= 0)
+ 
+-    def get_cpu_times(self, ret):
++    def cpu_times(self, ret):
+         self.assertTrue(ret.user >= 0)
+         self.assertTrue(ret.system >= 0)
+ 
+-    def get_memory_info(self, ret):
++    def memory_info(self, ret):
+         self.assertTrue(ret.rss >= 0)
+         self.assertTrue(ret.vms >= 0)
+ 
+-    def get_ext_memory_info(self, ret):
++    def memory_info_ex(self, ret):
+         for name in ret._fields:
+             self.assertTrue(getattr(ret, name) >= 0)
+         if POSIX and ret.vms != 0:
+@@ -1853,78 +2412,42 @@
+             assert ret.peak_nonpaged_pool >= ret.nonpaged_pool, ret
+             assert ret.peak_pagefile >= ret.pagefile, ret
+ 
+-    def get_open_files(self, ret):
++    def open_files(self, ret):
+         for f in ret:
+             if WINDOWS:
+                 assert f.fd == -1, f
+             else:
+-                assert isinstance(f.fd, int), f
++                self.assertIsInstance(f.fd, int)
+             assert os.path.isabs(f.path), f
+             assert os.path.isfile(f.path), f
+ 
+-    def get_num_fds(self, ret):
++    def num_fds(self, ret):
+         self.assertTrue(ret >= 0)
+ 
+-    def get_connections(self, ret):
+-        # all values are supposed to match Linux's tcp_states.h states
+-        # table across all platforms.
+-        valid_conn_states = ["ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1",
+-                             "FIN_WAIT2", "TIME_WAIT", "CLOSE", "CLOSE_WAIT",
+-                             "LAST_ACK", "LISTEN", "CLOSING", ""]
++    def connections(self, ret):
++        self.assertEqual(len(ret), len(set(ret)))
+         for conn in ret:
+-            self.assertIn(conn.type, (socket.SOCK_STREAM, socket.SOCK_DGRAM))
+-            self.assertIn(conn.family, (socket.AF_INET, socket.AF_INET6))
+-            check_ip_address(conn.local_address, conn.family)
+-            check_ip_address(conn.remote_address, conn.family)
+-            if conn.status not in valid_conn_states:
+-                self.fail("%s is not a valid status" %conn.status)
+-            # actually try to bind the local socket; ignore IPv6
+-            # sockets as their address might be represented as
+-            # an IPv4-mapped-address (e.g. "::127.0.0.1")
+-            # and that's rejected by bind()
+-            if conn.family == socket.AF_INET:
+-                s = socket.socket(conn.family, conn.type)
+-                s.bind((conn.local_address[0], 0))
+-                s.close()
++            check_connection_ntuple(conn)
+ 
+-            if not WINDOWS and hasattr(socket, 'fromfd'):
+-                dupsock = None
+-                try:
+-                    try:
+-                        dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
+-                    except (socket.error, OSError):
+-                        err = sys.exc_info()[1]
+-                        if err.args[0] == errno.EBADF:
+-                            continue
+-                        raise
+-                    # python >= 2.5
+-                    if hasattr(dupsock, "family"):
+-                        self.assertEqual(dupsock.family, conn.family)
+-                        self.assertEqual(dupsock.type, conn.type)
+-                finally:
+-                    if dupsock is not None:
+-                        dupsock.close()
+-
+-    def getcwd(self, ret):
++    def cwd(self, ret):
+         if ret is not None:  # BSD may return None
+             assert os.path.isabs(ret), ret
+             try:
+                 st = os.stat(ret)
+-            except OSError:
+-                err = sys.exc_info()[1]
++            except OSError as err:
+                 # directory has been removed in mean time
+                 if err.errno != errno.ENOENT:
+                     raise
+             else:
+                 self.assertTrue(stat.S_ISDIR(st.st_mode))
+ 
+-    def get_memory_percent(self, ret):
++    def memory_percent(self, ret):
+         assert 0 <= ret <= 100, ret
+ 
+     def is_running(self, ret):
+         self.assertTrue(ret)
+ 
+-    def get_cpu_affinity(self, ret):
++    def cpu_affinity(self, ret):
+         assert ret != [], ret
+ 
+     def terminal(self, ret):
+@@ -1932,28 +2455,29 @@
+             assert os.path.isabs(ret), ret
+             assert os.path.exists(ret), ret
+ 
+-    def get_memory_maps(self, ret):
++    def memory_maps(self, ret):
+         for nt in ret:
+             for fname in nt._fields:
+                 value = getattr(nt, fname)
+                 if fname == 'path':
+                     if not value.startswith('['):
+                         assert os.path.isabs(nt.path), nt.path
+-                        # commented as on Linux we might get '/foo/bar (deleted)'
+-                        #assert os.path.exists(nt.path), nt.path
++                        # commented as on Linux we might get
++                        # '/foo/bar (deleted)'
++                        # assert os.path.exists(nt.path), nt.path
+                 elif fname in ('addr', 'perms'):
+                     self.assertTrue(value)
+                 else:
+-                    assert isinstance(value, (int, long))
++                    self.assertIsInstance(value, (int, long))
+                     assert value >= 0, value
+ 
+-    def get_num_handles(self, ret):
++    def num_handles(self, ret):
+         if WINDOWS:
+-            assert ret >= 0
++            self.assertGreaterEqual(ret, 0)
+         else:
+-            assert ret > 0
++            self.assertGreaterEqual(ret, 0)
+ 
+-    def get_nice(self, ret):
++    def nice(self, ret):
+         if POSIX:
+             assert -20 <= ret <= 20, ret
+         else:
+@@ -1961,71 +2485,298 @@
+                           if x.endswith('_PRIORITY_CLASS')]
+             self.assertIn(ret, priorities)
+ 
+-    def get_num_ctx_switches(self, ret):
++    def num_ctx_switches(self, ret):
+         self.assertTrue(ret.voluntary >= 0)
+         self.assertTrue(ret.involuntary >= 0)
+ 
+-if hasattr(os, 'getuid'):
+-    class LimitedUserTestCase(TestCase):
+-        """Repeat the previous tests by using a limited user.
+-        Executed only on UNIX and only if the user who run the test script
+-        is root.
+-        """
+-        # the uid/gid the test suite runs under
++    def rlimit(self, ret):
++        self.assertEqual(len(ret), 2)
++        self.assertGreaterEqual(ret[0], -1)
++        self.assertGreaterEqual(ret[1], -1)
++
++
++# ===================================================================
++# --- Limited user tests
++# ===================================================================
++
[email protected](POSIX, "UNIX only")
[email protected](hasattr(os, 'getuid') and os.getuid() == 0,
++                     "super user privileges are required")
++class LimitedUserTestCase(TestProcess):
++    """Repeat the previous tests by using a limited user.
++    Executed only on UNIX and only if the user who run the test script
++    is root.
++    """
++    # the uid/gid the test suite runs under
++    if hasattr(os, 'getuid'):
+         PROCESS_UID = os.getuid()
+         PROCESS_GID = os.getgid()
+ 
+-        def __init__(self, *args, **kwargs):
+-            TestCase.__init__(self, *args, **kwargs)
+-            # re-define all existent test methods in order to
+-            # ignore AccessDenied exceptions
+-            for attr in [x for x in dir(self) if x.startswith('test')]:
+-                meth = getattr(self, attr)
+-                def test_(self):
+-                    try:
+-                        meth()
+-                    except psutil.AccessDenied:
+-                        pass
+-                setattr(self, attr, types.MethodType(test_, self))
+-
+-        def setUp(self):
+-            os.setegid(1000)
+-            os.seteuid(1000)
+-            TestCase.setUp(self)
+-
+-        def tearDown(self):
+-            os.setegid(self.PROCESS_UID)
+-            os.seteuid(self.PROCESS_GID)
+-            TestCase.tearDown(self)
++    def __init__(self, *args, **kwargs):
++        TestProcess.__init__(self, *args, **kwargs)
++        # re-define all existent test methods in order to
++        # ignore AccessDenied exceptions
++        for attr in [x for x in dir(self) if x.startswith('test')]:
++            meth = getattr(self, attr)
+ 
+-        def test_nice(self):
+-            try:
+-                psutil.Process(os.getpid()).set_nice(-1)
+-            except psutil.AccessDenied:
+-                pass
++            def test_(self):
++                try:
++                    meth()
++                except psutil.AccessDenied:
++                    pass
++            setattr(self, attr, types.MethodType(test_, self))
++
++    def setUp(self):
++        safe_remove(TESTFN)
++        TestProcess.setUp(self)
++        os.setegid(1000)
++        os.seteuid(1000)
++
++    def tearDown(self):
++        os.setegid(self.PROCESS_UID)
++        os.seteuid(self.PROCESS_GID)
++        TestProcess.tearDown(self)
++
++    def test_nice(self):
++        try:
++            psutil.Process().nice(-1)
++        except psutil.AccessDenied:
++            pass
++        else:
++            self.fail("exception not raised")
++
++    def test_zombie_process(self):
++        # causes problems if test test suite is run as root
++        pass
++
++
++# ===================================================================
++# --- Misc tests
++# ===================================================================
++
++class TestMisc(unittest.TestCase):
++    """Misc / generic tests."""
++
++    def test__str__(self):
++        sproc = get_test_subprocess()
++        p = psutil.Process(sproc.pid)
++        self.assertIn(str(sproc.pid), str(p))
++        # python shows up as 'Python' in cmdline on OS X so
++        # test fails on OS X
++        if not OSX:
++            self.assertIn(os.path.basename(PYTHON), str(p))
++        sproc = get_test_subprocess()
++        p = psutil.Process(sproc.pid)
++        p.kill()
++        p.wait()
++        self.assertIn(str(sproc.pid), str(p))
++        self.assertIn("terminated", str(p))
++
++    def test__eq__(self):
++        p1 = psutil.Process()
++        p2 = psutil.Process()
++        self.assertEqual(p1, p2)
++        p2._ident = (0, 0)
++        self.assertNotEqual(p1, p2)
++        self.assertNotEqual(p1, 'foo')
++
++    def test__hash__(self):
++        s = set([psutil.Process(), psutil.Process()])
++        self.assertEqual(len(s), 1)
++
++    def test__all__(self):
++        for name in dir(psutil):
++            if name in ('callable', 'error', 'namedtuple',
++                        'long', 'test', 'NUM_CPUS', 'BOOT_TIME',
++                        'TOTAL_PHYMEM'):
++                continue
++            if not name.startswith('_'):
++                try:
++                    __import__(name)
++                except ImportError:
++                    if name not in psutil.__all__:
++                        fun = getattr(psutil, name)
++                        if fun is None:
++                            continue
++                        if (fun.__doc__ is not None and
++                                'deprecated' not in fun.__doc__.lower()):
++                            self.fail('%r not in psutil.__all__' % name)
++
++    def test_memoize(self):
++        from psutil._common import memoize
++
++        @memoize
++        def foo(*args, **kwargs):
++            "foo docstring"
++            calls.append(None)
++            return (args, kwargs)
++
++        calls = []
++        # no args
++        for x in range(2):
++            ret = foo()
++            expected = ((), {})
++            self.assertEqual(ret, expected)
++            self.assertEqual(len(calls), 1)
++        # with args
++        for x in range(2):
++            ret = foo(1)
++            expected = ((1, ), {})
++            self.assertEqual(ret, expected)
++            self.assertEqual(len(calls), 2)
++        # with args + kwargs
++        for x in range(2):
++            ret = foo(1, bar=2)
++            expected = ((1, ), {'bar': 2})
++            self.assertEqual(ret, expected)
++            self.assertEqual(len(calls), 3)
++        # clear cache
++        foo.cache_clear()
++        ret = foo()
++        expected = ((), {})
++        self.assertEqual(ret, expected)
++        self.assertEqual(len(calls), 4)
++        # docstring
++        self.assertEqual(foo.__doc__, "foo docstring")
++
++    def test_serialization(self):
++        def check(ret):
++            if json is not None:
++                json.loads(json.dumps(ret))
++            a = pickle.dumps(ret)
++            b = pickle.loads(a)
++            self.assertEqual(ret, b)
++
++        check(psutil.Process().as_dict())
++        check(psutil.virtual_memory())
++        check(psutil.swap_memory())
++        check(psutil.cpu_times())
++        check(psutil.cpu_times_percent(interval=0))
++        check(psutil.net_io_counters())
++        if LINUX and not os.path.exists('/proc/diskstats'):
++            pass
++        else:
++            check(psutil.disk_io_counters())
++        check(psutil.disk_partitions())
++        check(psutil.disk_usage(os.getcwd()))
++        check(psutil.users())
++
++    def test_setup_script(self):
++        here = os.path.abspath(os.path.dirname(__file__))
++        setup_py = os.path.realpath(os.path.join(here, '..', 'setup.py'))
++        module = imp.load_source('setup', setup_py)
++        self.assertRaises(SystemExit, module.setup)
++
++
++# ===================================================================
++# --- Example script tests
++# ===================================================================
++
++class TestExampleScripts(unittest.TestCase):
++    """Tests for scripts in the examples directory."""
++
++    def assert_stdout(self, exe, args=None):
++        exe = os.path.join(EXAMPLES_DIR, exe)
++        if args:
++            exe = exe + ' ' + args
++        try:
++            out = sh(sys.executable + ' ' + exe).strip()
++        except RuntimeError as err:
++            if 'AccessDenied' in str(err):
++                return str(err)
+             else:
+-                self.fail("exception not raised")
++                raise
++        assert out, out
++        return out
+ 
++    def assert_syntax(self, exe, args=None):
++        exe = os.path.join(EXAMPLES_DIR, exe)
++        with open(exe, 'r') as f:
++            src = f.read()
++        ast.parse(src)
++
++    def test_check_presence(self):
++        # make sure all example scripts have a test method defined
++        meths = dir(self)
++        for name in os.listdir(EXAMPLES_DIR):
++            if name.endswith('.py'):
++                if 'test_' + os.path.splitext(name)[0] not in meths:
++                    # self.assert_stdout(name)
++                    self.fail('no test defined for %r script'
++                              % os.path.join(EXAMPLES_DIR, name))
+ 
+-def cleanup():
+-    reap_children(search_all=True)
+-    DEVNULL.close()
+-    safe_remove(TESTFN)
++    def test_disk_usage(self):
++        self.assert_stdout('disk_usage.py')
+ 
+-atexit.register(cleanup)
+-safe_remove(TESTFN)
++    def test_free(self):
++        self.assert_stdout('free.py')
++
++    def test_meminfo(self):
++        self.assert_stdout('meminfo.py')
++
++    def test_process_detail(self):
++        self.assert_stdout('process_detail.py')
++
++    def test_who(self):
++        self.assert_stdout('who.py')
++
++    def test_ps(self):
++        self.assert_stdout('ps.py')
+ 
+-def test_main():
++    def test_pstree(self):
++        self.assert_stdout('pstree.py')
++
++    def test_netstat(self):
++        self.assert_stdout('netstat.py')
++
++    @unittest.skipIf(TRAVIS, "permission denied on travis")
++    def test_ifconfig(self):
++        self.assert_stdout('ifconfig.py')
++
++    def test_pmap(self):
++        self.assert_stdout('pmap.py', args=str(os.getpid()))
++
++    @unittest.skipIf(ast is None,
++                     'ast module not available on this python version')
++    def test_killall(self):
++        self.assert_syntax('killall.py')
++
++    @unittest.skipIf(ast is None,
++                     'ast module not available on this python version')
++    def test_nettop(self):
++        self.assert_syntax('nettop.py')
++
++    @unittest.skipIf(ast is None,
++                     'ast module not available on this python version')
++    def test_top(self):
++        self.assert_syntax('top.py')
++
++    @unittest.skipIf(ast is None,
++                     'ast module not available on this python version')
++    def test_iotop(self):
++        self.assert_syntax('iotop.py')
++
++    def test_pidof(self):
++        output = self.assert_stdout('pidof.py %s' % psutil.Process().name())
++        self.assertIn(str(os.getpid()), output)
++
++
++def main():
+     tests = []
+     test_suite = unittest.TestSuite()
+-    tests.append(TestCase)
++    tests.append(TestSystemAPIs)
++    tests.append(TestProcess)
+     tests.append(TestFetchAllProcesses)
++    tests.append(TestMisc)
++    tests.append(TestExampleScripts)
++    tests.append(LimitedUserTestCase)
+ 
+     if POSIX:
+         from _posix import PosixSpecificTestCase
+         tests.append(PosixSpecificTestCase)
+ 
+     # import the specific platform test suite
++    stc = None
+     if LINUX:
+         from _linux import LinuxSpecificTestCase as stc
+     elif WINDOWS:
+@@ -2036,18 +2787,16 @@
+         from _osx import OSXSpecificTestCase as stc
+     elif BSD:
+         from _bsd import BSDSpecificTestCase as stc
+-    tests.append(stc)
+-
+-    if hasattr(os, 'getuid'):
+-        if os.getuid() == 0:
+-            tests.append(LimitedUserTestCase)
+-        else:
+-            atexit.register(warn, "Couldn't run limited user tests ("
+-                                  "super-user privileges are required)")
++    elif SUNOS:
++        from _sunos import SunOSSpecificTestCase as stc
++    if stc is not None:
++        tests.append(stc)
+ 
+     for test_class in tests:
+         test_suite.addTest(unittest.makeSuite(test_class))
+-    unittest.TextTestRunner(verbosity=2).run(test_suite)
++    result = unittest.TextTestRunner(verbosity=2).run(test_suite)
++    return result.wasSuccessful()
+ 
+ if __name__ == '__main__':
+-    test_main()
++    if not main():
++        sys.exit(1)
+--- mozjs-24.2.0/js/src/python/psutil/TODO	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/TODO	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,159 @@
++TODO
++====
++
++A collection of ideas and notes about stuff to implement in future versions.
++"#NNN" occurrences refer to bug tracker issues at:
++https://github.com/giampaolo/psutil/issues
++
++
++HIGHER PRIORITY
++===============
++
++ * OpenBSD support.
++
++ * #371: CPU temperature (apparently OSX and Linux only; on Linux it requires
++   lm-sensors lib).
++
++ * #269: expose network ifaces RX/TW queues. This should probably go into
++   net_if_stats(). Figure out on what platforms this is supported:
++   Linux: yes
++   Others: ?
++
++ * Process.threads(): thread names; patch for OSX available at:
++   https://code.google.com/p/plcrashreporter/issues/detail?id=65
++
++ * Asynchronous psutil.Popen (see http://bugs.python.org/issue1191964)
++
++
++LOWER PRIORITY
++==============
++
++ * #355: Android support.
++
++ * #276: GNU/Hurd support.
++
++ * #429: NetBSD support.
++
++ * DragonFlyBSD support?
++
++ * AIX support?
++
++ * examples/taskmgr-gui.py (using tk).
++
++ * system-wide number of open file descriptors:
++    * https://jira.hyperic.com/browse/SIGAR-30
++    * http://www.netadmintools.com/part295.html
++
++ * Number of system threads.
++    * Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684824(v=vs.85).aspx
++
++ * #357: what CPU a process is on.
++
++  * Doc / wiki which compares similarities between UNIX cli tools and psutil.
++   Example:
++   df -a  ->  psutil.disk_partitions
++   lsof   ->  psutil.Process.open_files() and psutil.Process.open_connections()
++   killall->  (actual script)
++   tty    ->  psutil.Process.terminal()
++   who    ->  psutil.users()
++
++
++DEBATABLE
++=========
++
++ * psutil.proc_tree() something which obtains a {pid:ppid, ...} dict for
++   all running processes in one shot. This can be factored out from
++   Process.children() and exposed as a first class function.
++   PROS: on Windows we can take advantage of _psutil_windows.ppid_map()
++   which is faster than iterating over all pids and calling ppid().
++   CONS: examples/pstree.py shows this can be easily done in the user code
++   so maybe it's not worth the addition.
++
++ * advanced cmdline interface exposing the whole API and providing different
++   kind of outputs (e.g. pprinted, colorized, json).
++
++ * [Linux]: process cgroups (http://en.wikipedia.org/wiki/Cgroups). They look
++   similar to prlimit() in terms of functionality but uglier (they should allow
++   limiting per-process network IO resources though, which is great). Needs
++   further reading.
++
++ * Should we expose OS constants (psutil.WINDOWS, psutil.OSX etc.)?
++
++ * Python 3.3. exposed different sched.h functions:
++   http://docs.python.org/dev/whatsnew/3.3.html#os
++   http://bugs.python.org/issue12655
++   http://docs.python.org/dev/library/os.html#interface-to-the-scheduler
++   It might be worth to take a look and figure out whether we can include some
++   of those in psutil.
++   Also, we can probably reimplement wait_pid() on POSIX which is currently
++   implemented as a busy-loop.
++
++ * Certain systems provide CPU times about process children. On those systems
++   Process.cpu_times() might return a (user, system, user_children,
++   system_children) ntuple.
++   * Linux: /proc/{PID}/stat
++   * Solaris: pr_cutime and pr_cstime
++   * FreeBSD: none
++   * OSX: none
++   * Windows: none
++
++ * ...also, os.times() provides 'elapsed' times as well.
++
++ * ...also Linux provides guest_time and cguest_time.
++
++ * Enrich exception classes hierarchy on Python >= 3.3 / post PEP-3151 so that:
++   - NoSuchProcess inherits from ProcessLookupError
++   - AccessDenied inherits from PermissionError
++   - TimeoutExpired inherits from TimeoutError (debatable)
++   See: http://docs.python.org/3/library/exceptions.html#os-exceptions
++
++ * Process.threads() might grow an extra "id" parameter so that it can be
++   used as such:
++
++    >>> p = psutil.Process(os.getpid())
++    >>> p.threads(id=psutil.current_thread_id())
++    thread(id=2539, user_time=0.03, system_time=0.02)
++    >>>
++
++   Note: this leads to questions such as "should we have a custom NoSuchThread
++   exception? Also see issue #418.
++
++   Note #2: this would work with os.getpid() only.
++   psutil.current_thread_id() might be desirable as per issue #418 though.
++
++  * should psutil.TimeoutExpired exception have a 'msg' kwarg similar to
++    NoSuchProcess and AccessDenied? Not that we need it, but currently we
++    cannot raise a TimeoutExpired exception with a specific error string.
++
++  * process_iter() might grow an "attrs" parameter similar to Process.as_dict()
++    invoke the necessary methods and include the results into a "cache"
++    attribute attached to the returned Process instances so that one can avoid
++    catching NSP and AccessDenied:
++        for p in process_iter(attrs=['cpu_percent']):
++            print(p.cache['cpu_percent'])
++    This also leads questions as whether we should introduce a sorting order.
++
++  * round Process.memory_percent() result?
++
++  * #550: number of threads per core.
++
++  * Have psutil.Process().cpu_affinity([]) be an alias for "all CPUs"?
++
++
++COMPATIBILITY BREAKAGE
++======================
++
++Removals (will likely happen in 2.2):
++
++ * (S) psutil.Process.nice  (deprecated in 0.5.0)
++ * (S) get_process_list  (deprecated in 0.5.0)
++ * (S) psutil.*mem* functions  (deprecated in 0.3.0 and 0.6.0)
++ * (M) psutil.network_io_counters  (deprecated in 1.0.0)
++ * (M) local_address and remote_address Process.connection() namedtuple fields
++       (deprecated in 1.0.0)
++
++
++REJECTED IDEAS
++==============
++
++STUB
+\ No newline at end of file
+--- mozjs-24.2.0/js/src/python/psutil/tox.ini	1969-12-31 16:00:00.000000000 -0800
++++ mozjs-24.2.0/js/src/python/psutil/tox.ini	2015-06-17 19:33:33.000000000 -0700
+@@ -0,0 +1,32 @@
++# Tox (http://tox.testrun.org/) is a tool for running tests
++# in multiple virtualenvs. This configuration file will run the
++# test suite on all supported python versions.
++# To use it run "pip install tox" and then run "tox" from this
++# directory.
++
++[tox]
++envlist = py26, py27, py32, py33, py34
++
++[testenv]
++deps =
++    flake8
++    pytest
++    py26: ipaddress
++    py26: mock
++    py26: unittest2
++    py27: ipaddress
++    py27: mock
++    py32: ipaddress
++    py32: mock
++    py33: ipaddress
++
++setenv =
++    PYTHONPATH = {toxinidir}/test
++
++commands =
++    py.test {posargs}
++    git ls-files | grep \\.py$ | xargs flake8
++
++# suppress "WARNING: 'git' command found but not installed in testenv
++whitelist_externals = git
++usedevelop = True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/01-psutil.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,28 @@
+Not appropriate for upstream; presumed fixed in newer versions.
+
+--- mozjs-24.2.0/js/src/build/virtualenv/populate_virtualenv.py	2013-10-29 13:40:23.000000000 -0700
++++ mozjs-24.2.0/js/src/build/virtualenv/populate_virtualenv.py	2015-06-27 16:28:50.182353664 -0700
+@@ -251,10 +251,8 @@
+         # work.
+         #
+         # We also ignore environment variables that may have been altered by
+-        # configure or a mozconfig activated in the current shell. We trust
+-        # Python is smart enough to find a proper compiler and to use the
+-        # proper compiler flags. If it isn't your Python is likely broken.
+-        IGNORE_ENV_VARIABLES = ('CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS',
++        # configure or a mozconfig activated in the current shell.
++        IGNORE_ENV_VARIABLES = ('CFLAGS', 'CXXFLAGS', 'LDFLAGS',
+             'PYTHONDONTWRITEBYTECODE')
+ 
+         try:
+--- mozjs-24.2.0/js/src/python/mozbuild/mozbuild/controller/building.py	2013-10-29 13:40:25.000000000 -0700
++++ mozjs-24.2.0/js/src/python/mozbuild/mozbuild/controller/building.py	2015-06-27 16:50:05.967006567 -0700
+@@ -12,7 +12,7 @@
+ from collections import namedtuple
+ 
+ # keep in sync with psutil os support, see psutil/__init__.py
+-if sys.platform.startswith("freebsd") or sys.platform.startswith("darwin") or sys.platform.startswith("win32") or sys.platform.startswith("linux"):
++if sys.platform.startswith("freebsd") or sys.platform.startswith("darwin") or sys.platform.startswith("win32") or sys.platform.startswith("linux") or sys.platform.startswith("sunos"):
+     try:
+         import psutil
+     except ImportError:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/02-nspr.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,32 @@
+Not appropriate for upstream; hack to use pkg-config since we don't ship
+nspr-config scripts.
+
+--- mozjs-24.2.0/js/src/configure	2013-12-11 14:23:20.000000000 -0800
++++ mozjs-24.2.0/js/src/configure	2015-06-27 16:53:57.146376719 -0700
+@@ -12402,7 +12402,7 @@
+ 	if test "$NSPR_CONFIG" != "no"; then
+ 		NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags`
+ 		NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs`
+-		NSPR_VERSION_STRING=`$NSPR_CONFIG $nspr_config_args --version`	
++		NSPR_VERSION_STRING=`$NSPR_CONFIG $nspr_config_args --modversion`	
+ 	elif test -n "${NO_NSPR_CONFIG_SYSTEM_VERSION}"; then
+ 	    NSPR_CFLAGS="${NO_NSPR_CONFIG_SYSTEM_CFLAGS}"
+ 		NSPR_LIBS="${NO_NSPR_CONFIG_SYSTEM_LDFLAGS}"
+--- mozjs-24.2.0/js/src/configure	2016-06-23 16:01:29.775679815 +0000
++++ mozjs-24.2.0/js/src/configure	2016-06-23 16:13:04.806287066 +0000
+@@ -12351,13 +12351,13 @@
+ 		nspr_config_major_version=`echo $NSPR_VERSION_STRING | \
+ 			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+ 		nspr_config_minor_version=`echo $NSPR_VERSION_STRING | \
+-			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
++			sed 's/\([0-9]*\).\([0-11]*\).\([0-9]*\)/\2/'`
+ 		nspr_config_micro_version=`echo $NSPR_VERSION_STRING | \
+ 			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+ 		min_nspr_major_version=`echo $min_nspr_version | \
+ 			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+ 		min_nspr_minor_version=`echo $min_nspr_version | \
+-			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
++			sed 's/\([0-9]*\).\([0-11]*\).\([0-9]*\)/\2/'`
+ 		min_nspr_micro_version=`echo $min_nspr_version | \
+ 			sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+ 		if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/03-readline.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,24 @@
+Solaris-specific hack for library dependencies.
+
+Not appropriate for upstream.
+
+--- mozjs-24.2.0/js/src/configure	2015-06-27 16:57:49.991630432 -0700
++++ mozjs-24.2.0.new/js/src/configure	2015-06-27 16:57:24.260169859 -0700
+@@ -14593,7 +14593,7 @@
+   echo $ac_n "(cached) $ac_c" 1>&6
+ else
+   ac_save_LIBS="$LIBS"
+-LIBS="-lreadline  $LIBS"
++LIBS="-lreadline -lcurses $LIBS"
+ cat > conftest.$ac_ext <<EOF
+ #line 14599 "configure"
+ #include "confdefs.h"
+@@ -14621,7 +14621,7 @@
+ fi
+ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+   echo "$ac_t""yes" 1>&6
+-  EDITLINE_LIBS="-lreadline"
++  EDITLINE_LIBS="-lreadline -lcurses"
+ else
+   echo "$ac_t""no" 1>&6
+ { echo "configure: error: No system readline library found." 1>&2; exit 1; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/04-madvise.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,16 @@
+Solaris madvise specifies caddr_t* as first parameter whereas Linux uses
+void*.
+
+XXX file upstream bug?
+
+--- mozjs-24.2.0/mfbt/Poison.cpp	2013-10-29 13:40:19.000000000 -0700
++++ mozjs-24.2.0/mfbt/Poison.cpp	2015-06-27 17:20:54.914745595 -0700
+@@ -125,7 +125,7 @@
+ static bool
+ ProbeRegion(uintptr_t region, uintptr_t size)
+ {
+-  if (madvise(reinterpret_cast<void*>(region), size, MADV_NORMAL)) {
++  if (madvise(reinterpret_cast<char*>(region), size, MADV_NORMAL)) {
+     return true;
+   } else {
+     return false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/05-ion_AsmJS_x86.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,14 @@
+Add missing define on Solaris.
+
+XXX file upstream bug
+
+--- mozjs-24.2.0/js/src/jit/AsmJSSignalHandlers.cpp	2013-10-29 13:40:19.000000000 -0700
++++ mozjs-24.2.0.new/js/src/jit/AsmJSSignalHandlers.cpp	2015-06-27 18:27:41.867039386 -0700
+@@ -60,6 +60,7 @@
+ # if defined(__linux__)
+ #  define XMM_sig(p,i) ((p)->uc_mcontext.fpregs->_xmm[i])
+ # else
++#  define REG_EIP EIP
+ #  define XMM_sig(p,i) ((p)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[i])
+ # endif
+ # define EIP_sig(p) ((p)->uc_mcontext.gregs[REG_EIP])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/06-bits.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,512 @@
+Backported fixes from newer upstream version to fix 32/64-bit combined builds.
+
+Not appropriate for upstream.
+
+--- mozjs-24.2.0/js/public/HashTable.h	2013-12-11 14:22:50.000000000 -0800
++++ mozjs-31.2.0/js/public/HashTable.h	2014-10-10 11:31:12.000000000 -0700
+@@ -501,1 +501,1 @@
+-#if JS_BYTES_PER_WORD == 4
++#if JS_BITS_PER_WORD == 32
+--- mozjs-24.2.0/js/public/HeapAPI.h	2013-10-29 13:40:26.000000000 -0700
++++ mozjs-31.2.0/js/public/HeapAPI.h	2014-10-10 11:31:12.000000000 -0700
+@@ -94,6 +99,7 @@
+     uintptr_t *bitmap = GetGCThingMarkBitmap(thing);
+-    *maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD);
+-    *wordp = &bitmap[bit / JS_BITS_PER_WORD];
++    const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT;
++    *maskp = uintptr_t(1) << (bit % nbits);
++    *wordp = &bitmap[bit / nbits];
+ }
+ 
+ static JS_ALWAYS_INLINE JS::shadow::ArenaHeader *
+ GetGCThingArena(void *thing)
+--- mozjs-24.2.0/js/public/TemplateLib.h	2013-10-29 13:40:26.000000000 -0700
++++ mozjs-24.2.0/js/public/TemplateLib.h	2015-06-29 13:41:04.004359799 -0700
+@@ -7,6 +7,7 @@
+ #ifndef js_TemplateLib_h
+ #define js_TemplateLib_h
+ 
++#include <limits.h>
+ #include "jstypes.h"
+ 
+ /*
+@@ -60,7 +61,7 @@
+ 
+ /* Compute the number of bits in the given unsigned type. */
+ template <class T> struct BitSize {
+-    static const size_t result = sizeof(T) * JS_BITS_PER_BYTE;
++    static const size_t result = sizeof(T) * CHAR_BIT;
+ };
+ 
+ /*
+--- mozjs-24.2.0/js/public/Utility.h	2013-12-11 14:22:50.000000000 -0800
++++ mozjs-24.2.0/js/public/Utility.h	2015-06-29 12:51:42.314214334 -0700
+@@ -312,14 +312,12 @@
+         (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1);            \
+     JS_END_MACRO
+ 
+-#if JS_BYTES_PER_WORD == 4
++#if JS_BITS_PER_WORD == 32
+ #  define js_FloorLog2wImpl(n)                                                \
+     ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
+-#elif JS_BYTES_PER_WORD == 8
++#else
+ #  define js_FloorLog2wImpl(n)                                                \
+     ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
+-#else
+-# error "NOT SUPPORTED"
+ #endif
+ 
+ JS_END_EXTERN_C
+--- mozjs-24.2.0/js/src/configure	2015-06-29 11:33:21.539108937 -0700
++++ mozjs-31.2.0/js/src/configure	2014-10-10 11:49:47.000000000 -0700
+@@ -9091,80 +9448,16 @@
+   echo "$ac_t""no" 1>&6
+ fi
+ 
+-
+-echo $ac_n "checking for the size of void*""... $ac_c" 1>&6
+-echo "configure:9097: checking for the size of void*" >&5
+-if eval "test \"`echo '$''{'moz_cv_size_of_JS_BYTES_PER_WORD'+set}'`\" = set"; then
+-  echo $ac_n "(cached) $ac_c" 1>&6
+-else
+-  
+-  moz_cv_size_of_JS_BYTES_PER_WORD=
+-  for size in 4 8; do
+-    cat > conftest.$ac_ext <<EOF
+-#line 9105 "configure"
+-#include "confdefs.h"
+-
+-int main() {
+-
+-                     int a[sizeof (void*) == $size ? 1 : -1];
+-                     return 0;
+-                   
+-; return 0; }
+-EOF
+-if { (eval echo configure:9115: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+-  rm -rf conftest*
+-  moz_cv_size_of_JS_BYTES_PER_WORD=$size; break
+-else
+-  echo "configure: failed program was:" >&5
+-  cat conftest.$ac_ext >&5
+-fi
+-rm -f conftest*
+-  done
+-  if test ! "$moz_cv_size_of_JS_BYTES_PER_WORD"; then
+-    { echo "configure: error: No size found for void*" 1>&2; exit 1; }
+-  fi
+-
+-fi
+-
+-echo "$ac_t""$moz_cv_size_of_JS_BYTES_PER_WORD" 1>&6
+-cat >> confdefs.pytmp <<EOF
+-    (''' JS_BYTES_PER_WORD ''', r''' $moz_cv_size_of_JS_BYTES_PER_WORD ''')
+-EOF
+-cat >> confdefs.h <<EOF
+-#define JS_BYTES_PER_WORD $moz_cv_size_of_JS_BYTES_PER_WORD
+-EOF
+-
+-
+-if test "$moz_cv_size_of_JS_BYTES_PER_WORD" -eq "4"; then
+-  cat >> confdefs.pytmp <<\EOF
+-    (''' JS_BITS_PER_WORD_LOG2 ''', r''' 5 ''')
+-EOF
+-cat >> confdefs.h <<\EOF
+-#define JS_BITS_PER_WORD_LOG2 5
+-EOF
+-
+-elif test "$moz_cv_size_of_JS_BYTES_PER_WORD" -eq "8"; then
+-  cat >> confdefs.pytmp <<\EOF
+-    (''' JS_BITS_PER_WORD_LOG2 ''', r''' 6 ''')
+-EOF
+-cat >> confdefs.h <<\EOF
+-#define JS_BITS_PER_WORD_LOG2 6
+-EOF
+-
+-else
+-  { echo "configure: error: Unexpected JS_BYTES_PER_WORD" 1>&2; exit 1; }
+-fi
+-
+  for ac_hdr in endian.h
+   do
+        ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+   echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+ echo "configure:9163: checking for $ac_hdr" >&5
+   if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+   echo $ac_n "(cached) $ac_c" 1>&6
+ else
+    cat > conftest.$ac_ext <<EOF
+ #line 9168 "configure"
+ #include "confdefs.h"
+ 
+ #include <$ac_hdr>
+--- mozjs-24.2.0/js/src/js-config.h.in	2013-12-11 14:22:50.000000000 -0800
++++ mozjs-31.2.0/js/src/js-config.h.in	2014-10-10 11:31:12.000000000 -0700
+@@ -40,16 +40,12 @@
+    useable.  See jscpucfg.h.  */
+ #undef JS_HAVE_SYS_ISA_DEFS_H
+ 
+-/* The configure script defines these if it doesn't #define
+-   JS_HAVE_STDINT_H.  */
+-#undef JS_BYTES_PER_WORD
+-
+ /* Some mozilla code uses JS-friend APIs that depend on JS_METHODJIT being
+    correct. */
+ #undef JS_METHODJIT
+ 
+ /* MOZILLA JSAPI version number components */
+ #undef MOZJS_MAJOR_VERSION
+ #undef MOZJS_MINOR_VERSION
+ 
+ #endif /* js_config_h___ */
+--- mozjs-24.2.0/js/src/jscpucfg.h	2013-10-29 13:40:20.000000000 -0700
++++ mozjs-31.2.0/js/src/jscpucfg.h	2014-10-10 11:31:12.000000000 -0700
+@@ -14,13 +14,11 @@
+ # if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)
+ #  define IS_LITTLE_ENDIAN 1
+ #  undef  IS_BIG_ENDIAN
+-#  define JS_BYTES_PER_WORD   8
+-#  define JS_BITS_PER_WORD_LOG2   6
+ # else  /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */
+ #  error "CPU type is unknown"
+ # endif /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */
+ 
+-#elif defined(_WIN32) || defined(XP_OS2)
++#elif defined(_WIN32)
+ 
+ # ifdef __WATCOMC__
+ #  define HAVE_VA_LIST_AS_ARRAY 1
+@@ -28,10 +26,8 @@
+ 
+ # define IS_LITTLE_ENDIAN 1
+ # undef  IS_BIG_ENDIAN
+-# define JS_BYTES_PER_WORD   4
+-# define JS_BITS_PER_WORD_LOG2   5
+ 
+-#elif defined(__APPLE__)
++#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__)
+ # if __LITTLE_ENDIAN__
+ #  define IS_LITTLE_ENDIAN 1
+ #  undef  IS_BIG_ENDIAN
+--- mozjs-24.2.0/js/src/jsfriendapi.h	2013-12-11 14:22:50.000000000 -0800
++++ mozjs-31.2.0/js/src/jsfriendapi.h	2014-10-10 11:31:12.000000000 -0700
+@@ -1660,1 +1660,1 @@
+-JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD);
++JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*));
+--- mozjs-24.2.0/js/src/ds/BitArray.h	2013-10-29 13:40:26.000000000 -0700
++++ mozjs-31.2.0/js/src/ds/BitArray.h	2014-10-10 10:58:07.000000000 -0700
+@@ -7,22 +7,31 @@
+ #ifndef ds_BitArray_h
+ #define ds_BitArray_h
+ 
+-#include "jstypes.h" 
++#include "js/TemplateLib.h"
+ 
+-#include "js/TemplateLib.h" 
++#include <limits.h>
++
++#include "jstypes.h"
+ 
+ namespace js {
+ 
+ template <size_t nbits>
+-class BitArray {
++class BitArray
++{
+   private:
+-    static const size_t numSlots =
+-        nbits / JS_BITS_PER_WORD + (nbits % JS_BITS_PER_WORD == 0 ? 0 : 1);
++    static const size_t bitsPerElement = sizeof(uintptr_t) * CHAR_BIT;
++    static const size_t numSlots = nbits / bitsPerElement + (nbits % bitsPerElement == 0 ? 0 : 1);
++    static const size_t paddingBits = (numSlots * bitsPerElement) - nbits;
++    static_assert(paddingBits < bitsPerElement, "More padding bits than expected.");
++    static const uintptr_t paddingMask = uintptr_t(-1) >> paddingBits;
++
+     uintptr_t map[numSlots];
+ 
+   public:
+     void clear(bool value) {
+         memset(map, value ? 0xFF : 0, sizeof(map));
++        if (value)
++            map[numSlots - 1] &= paddingMask;
+     }
+ 
+     inline bool get(size_t offset) const {
+@@ -31,13 +40,13 @@
+         return map[index] & mask;
+     }
+ 
+-    inline void set(size_t offset) {
++    void set(size_t offset) {
+         uintptr_t index, mask;
+         getMarkWordAndMask(offset, &index, &mask);
+         map[index] |= mask;
+     }
+ 
+-    inline void unset(size_t offset) {
++    void unset(size_t offset) {
+         uintptr_t index, mask;
+         getMarkWordAndMask(offset, &index, &mask);
+         map[index] &= ~mask;
+@@ -54,8 +63,10 @@
+   private:
+     inline void getMarkWordAndMask(size_t offset,
+                                    uintptr_t *indexp, uintptr_t *maskp) const {
+-        *indexp = offset >> tl::FloorLog2<JS_BITS_PER_WORD>::result;
+-        *maskp = uintptr_t(1) << (offset & (JS_BITS_PER_WORD - 1));
++        static_assert(bitsPerElement == 32 || bitsPerElement == 64,
++                      "unexpected bitsPerElement value");
++        *indexp = offset / bitsPerElement;
++        *maskp = uintptr_t(1) << (offset % bitsPerElement);
+     }
+ };
+ 
+--- mozjs-24.2.0/js/src/frontend/BytecodeEmitter.cpp	2013-10-29 13:40:26.000000000 -0700
++++ mozjs-31.2.0/js/src/frontend/BytecodeEmitter.cpp	2014-10-10 11:31:12.000000000 -0700
+@@ -2309,19 +2606,19 @@
+                 i += JS_BIT(16);
+             if (i >= intmap_bitlen) {
+                 if (!intmap &&
+-                    i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) {
++                    size_t(i) < (INTMAP_LENGTH * JS_BITMAP_NBITS)) {
+                     intmap = intmap_space;
+-                    intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2;
++                    intmap_bitlen = INTMAP_LENGTH * JS_BITMAP_NBITS;
+                 } else {
+                     /* Just grab 8K for the worst-case bitmap. */
+                     intmap_bitlen = JS_BIT(16);
+-                    intmap = cx->pod_malloc<jsbitmap>(JS_BIT(16) >> JS_BITS_PER_WORD_LOG2);
++                    intmap = cx->pod_malloc<jsbitmap>(JS_BIT(16) / JS_BITMAP_NBITS);
+                     if (!intmap) {
+                         JS_ReportOutOfMemory(cx);
+                         return false;
+                     }
+                 }
+-                memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
++                memset(intmap, 0, size_t(intmap_bitlen) / CHAR_BIT);
+             }
+             if (JS_TEST_BIT(intmap, i)) {
+                 switchOp = JSOP_CONDSWITCH;
+--- mozjs-24.2.0/js/src/gc/Heap.h	2013-10-29 13:40:26.000000000 -0700
++++ mozjs-31.2.0/js/src/gc/Heap.h	2014-10-10 11:31:12.000000000 -0700
+@@ -711,12 +740,10 @@
+     }
+ 
+     uintptr_t *arenaBits(ArenaHeader *aheader) {
+-        /*
+-         * We assume that the part of the bitmap corresponding to the arena
+-         * has the exact number of words so we do not need to deal with a word
+-         * that covers bits from two arenas.
+-         */
+-        JS_STATIC_ASSERT(ArenaBitmapBits == ArenaBitmapWords * JS_BITS_PER_WORD);
++        static_assert(ArenaBitmapBits == ArenaBitmapWords * JS_BITS_PER_WORD,
++                      "We assume that the part of the bitmap corresponding to the arena "
++                      "has the exact number of words so we do not need to deal with a word "
++                      "that covers bits from two arenas.");
+ 
+         uintptr_t *word, unused;
+         getMarkWordAndMask(reinterpret_cast<Cell *>(aheader->address()), BLACK, &word, &unused);
+--- mozjs-24.2.0/js/src/jit/BaselineIC.cpp	2013-12-06 14:52:35.000000000 -0800
++++ mozjs-31.2.0/js/src/jit/BaselineIC.cpp	2014-10-10 11:31:12.000000000 -0700
+@@ -18,6 +18,8 @@
+ #include "jit/IonFrames-inl.h"
+ #include "vm/Interpreter-inl.h"
+ 
++#include "js/TemplateLib.h"
++
+ namespace js {
+ namespace jit {
+ 
+@@ -3985,11 +4761,13 @@
+ 
+     // In tempReg, calculate index of word containing bit: (idx >> logBitsPerWord)
+     masm.movePtr(idxReg, tempReg);
+-    masm.rshiftPtr(Imm32(JS_BITS_PER_WORD_LOG2), tempReg);
++    const uint32_t shift = tl::FloorLog2<(sizeof(size_t) * JS_BITS_PER_BYTE)>::result;
++    JS_ASSERT(shift == 5 || shift == 6);
++    masm.rshiftPtr(Imm32(shift), tempReg);
+     masm.loadPtr(BaseIndex(scratchReg, tempReg, ScaleFromElemWidth(sizeof(size_t))), scratchReg);
+ 
+     // Don't bother testing specific bit, if any bit is set in the word, fail.
+     masm.branchPtr(Assembler::NotEqual, scratchReg, ImmWord((size_t)0), &failureReconstructInputs);
+ 
+     // Load the value.  use scratchReg and tempReg to form a ValueOperand to load into.
+     masm.addPtr(Imm32(ArgumentsData::offsetOfArgs()), argData);
+--- mozjs-24.2.0/js/src/jit/IonCaches.cpp	2013-12-06 14:52:35.000000000 -0800
++++ mozjs-31.2.0/js/src/jit/IonCaches.cpp	2014-10-10 11:31:12.000000000 -0700
+@@ -20,6 +20,8 @@
+ 
+ #include "vm/Interpreter-inl.h"
+ 
++#include "js/TemplateLib.h"
++
+ using namespace js;
+ using namespace js::jit;
+ 
+@@ -2421,11 +3341,13 @@
+     masm.loadPtr(Address(tmpReg, offsetof(ArgumentsData, deletedBits)), tmpReg);
+ 
+     // In tempReg, calculate index of word containing bit: (idx >> logBitsPerWord)
+-    masm.rshiftPtr(Imm32(JS_BITS_PER_WORD_LOG2), indexReg);
++    const uint32_t shift = tl::FloorLog2<(sizeof(size_t) * JS_BITS_PER_BYTE)>::result;
++    JS_ASSERT(shift == 5 || shift == 6);
++    masm.rshiftPtr(Imm32(shift), indexReg);
+     masm.loadPtr(BaseIndex(tmpReg, indexReg, ScaleFromElemWidth(sizeof(size_t))), tmpReg);
+ 
+     // Don't bother testing specific bit, if any bit is set in the word, fail.
+     masm.branchPtr(Assembler::NotEqual, tmpReg, ImmWord((size_t)0), &failurePopIndex);
+ 
+     // Get the address to load from into tmpReg
+     masm.loadPrivate(Address(object(), ArgumentsObject::getDataSlotOffset()), tmpReg);
+--- mozjs-24.2.0/js/src/jscrashreport.cpp	2013-10-29 13:40:20.000000000 -0700
++++ mozjs-31.2.0/js/src/jscrashreport.cpp	2014-10-10 11:31:12.000000000 -0700
+@@ -15,10 +15,10 @@
+ using namespace js;
+ using namespace js::crash;
+ 
+-const static int stack_snapshot_max_size = 32768;
+-
+ #if defined(XP_WIN)
+ 
++static const int stack_snapshot_max_size = 32768;
++
+ #include <windows.h>
+ 
+ static bool
+@@ -46,14 +46,14 @@
+     *stack_len = len;
+ 
+     /* Get the register state. */
+-#if defined(_MSC_VER) && JS_BITS_PER_WORD == 32
++#if defined(_MSC_VER) && defined(_M_IX86)
+     /* ASM version for win2k that doesn't support RtlCaptureContext */
+     uint32_t vip, vsp, vbp;
+     __asm {
+-    Label:
++    MyLabel:
+         mov [vbp], ebp;
+         mov [vsp], esp;
+-        mov eax, [Label];
++        mov eax, [MyLabel];
+         mov [vip], eax;
+     }
+     regs->ip = vip;
+@@ -62,14 +62,16 @@
+ #else
+     CONTEXT context;
+     RtlCaptureContext(&context);
+-#if JS_BITS_PER_WORD == 32
++#if defined(_M_IX86)
+     regs->ip = context.Eip;
+     regs->sp = context.Esp;
+     regs->bp = context.Ebp;
+-#else
++#elif defined(_M_X64)
+     regs->ip = context.Rip;
+     regs->sp = context.Rsp;
+     regs->bp = context.Rbp;
++#else
++#error unknown cpu architecture
+ #endif
+ #endif
+ 
+@@ -80,9 +82,9 @@
+ 
+ #elif 0
+ 
+-#include <unistd.h>
+-#include <ucontext.h>
+ #include <sys/mman.h>
++#include <ucontext.h>
++#include <unistd.h>
+ 
+ static bool
+ GetStack(uint64_t *stack, uint64_t *stack_len, CrashRegisters *regs, char *buffer, size_t size)
+@@ -114,14 +116,16 @@
+     if (getcontext(&context) != 0)
+ 	return false;
+ 
+-#if JS_BITS_PER_WORD == 64
++#if defined(__x86_64__)
+     regs->sp = (uint64_t)context.uc_mcontext.gregs[REG_RSP];
+     regs->bp = (uint64_t)context.uc_mcontext.gregs[REG_RBP];
+     regs->ip = (uint64_t)context.uc_mcontext.gregs[REG_RIP];
+-#elif JS_BITS_PER_WORD == 32
++#elif defined(__i386__)
+     regs->sp = (uint64_t)context.uc_mcontext.gregs[REG_ESP];
+     regs->bp = (uint64_t)context.uc_mcontext.gregs[REG_EBP];
+     regs->ip = (uint64_t)context.uc_mcontext.gregs[REG_EIP];
++#else
++#error unknown cpu architecture
+ #endif
+ 
+     js_memcpy(buffer, (void *)p, len);
+--- mozjs-24.2.0/js/src/jstypes.h	2013-10-29 13:40:20.000000000 -0700
++++ mozjs-31.2.0/js/src/jstypes.h	2014-10-10 11:31:12.000000000 -0700
+@@ -244,7 +184,11 @@
+ #define JS_BITS_PER_BYTE 8
+ #define JS_BITS_PER_BYTE_LOG2 3
+ 
+-#define JS_BITS_PER_WORD (JS_BITS_PER_BYTE * JS_BYTES_PER_WORD)
++#if defined(JS_64BIT)
++# define JS_BITS_PER_WORD 64
++#else
++# define JS_BITS_PER_WORD 32
++#endif
+ 
+ /***********************************************************************
+ ** MACROS:      JS_FUNC_TO_DATA_PTR
+--- mozjs-24.2.0/js/src/jsutil.h	2013-12-11 14:22:51.000000000 -0800
++++ mozjs-31.2.0/js/src/jsutil.h	2014-10-10 11:31:12.000000000 -0700
+@@ -208,16 +214,18 @@
+ 
+ /* A bit array is an array of bits represented by an array of words (size_t). */
+ 
++static const size_t BitArrayElementBits = sizeof(size_t) * CHAR_BIT;
++
+ static inline unsigned
+ NumWordsForBitArrayOfLength(size_t length)
+ {
+-    return (length + (JS_BITS_PER_WORD - 1)) / JS_BITS_PER_WORD;
++    return (length + (BitArrayElementBits - 1)) / BitArrayElementBits;
+ }
+ 
+ static inline unsigned
+ BitArrayIndexToWordIndex(size_t length, size_t bitIndex)
+ {
+-    unsigned wordIndex = bitIndex / JS_BITS_PER_WORD;
++    unsigned wordIndex = bitIndex / BitArrayElementBits;
+     JS_ASSERT(wordIndex < length);
+     return wordIndex;
+ }
+@@ -225,7 +233,7 @@
+ static inline size_t
+ BitArrayIndexToWordMask(size_t i)
+ {
+-    return size_t(1) << (i % JS_BITS_PER_WORD);
++    return size_t(1) << (i % BitArrayElementBits);
+ }
+ 
+ static inline bool
+@@ -345,12 +321,13 @@
+ 
+ /* A jsbitmap_t is a long integer that can be used for bitmaps. */
+ typedef size_t jsbitmap;
+-#define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &      \
+-                                 ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
+-#define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |=     \
+-                                 ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
+-#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &=     \
+-                                 ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
++#define JS_BITMAP_NBITS (sizeof(jsbitmap) * CHAR_BIT)
++#define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)/JS_BITMAP_NBITS] &             \
++                                 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
++#define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)/JS_BITMAP_NBITS] |=            \
++                                 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
++#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] &=            \
++                                 ~(jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
+ 
+ /* Wrapper for various macros to stop warnings coming from their expansions. */
+ #if defined(__clang__)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/desktop/mozjs-24/patches/07-mileston.patch	Fri Jul 01 13:03:40 2016 +0000
@@ -0,0 +1,13 @@
+Potentially evaluate to send upstream for working for perl 5.22
+
+--- mozjs-24.2.0/js/src/config/milestone.pl	2013-11-19 19:42:43.000000000 +0000
++++ mozjs-24.2.0/js/src/config/milestone.pl	2016-06-24 08:58:01.126396537 +0000
+@@ -56,7 +56,7 @@
+ #
+ my $milestone = Moz::Milestone::getOfficialMilestone($MILESTONE_FILE);
+ 
+-if (defined(@TEMPLATE_FILE)) {
++if ((@TEMPLATE_FILE)) {
+   my $TFILE;
+ 
+   foreach $TFILE (@TEMPLATE_FILE) {