--- /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">>>></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>«</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">
++ © 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(
+ ¤t.duration[DEVSTAT_READ], NULL), // r time
+ (long long)devstat_compute_etime(
+- ¤t.duration[DEVSTAT_WRITE], NULL) // w time
+- );
++ ¤t.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(ðcmd, 0, sizeof ethcmd);
++ ethcmd.cmd = ETHTOOL_GSET;
++ ifr.ifr_data = (caddr_t)ðcmd;
++ 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,
+- ¤tDirectory, sizeof(currentDirectory), NULL))
+-#else
+- if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 0x24,
+- ¤tDirectory, 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,
++ ¤tDirectory, sizeof(currentDirectory), NULL))
++#else
++ if (!ReadProcessMemory(processHandle,
++ (PCHAR)rtlUserProcParamsAddress + 0x24,
++ ¤tDirectory, 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