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: g.rodola@gmail.com
+
+Contributors
+============
N: Jay Loden
C: NJ, USA
E: jloden@gmail.com
+D: original co-author, initial design/bootstrap and occasional bug fixes
-
-Contributors
-============
-
N: Jeremy Whitlock
E: jcscoobyrs@gmail.com
+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: yanraber@gmail.com
-D: help on Windows development
+D: help on Windows development (initial version of Process.username())
+
+N: Justin Venus
+E: justin.venus@gmail.com
+D: Solaris support
+I: 18
N: Dave Daeschler
C: USA
E: david.daeschler@gmail.com
-D: initial design/bootstrap and continuing bug fixes
+D: some contributions to initial design/bootstrap plus occasional bug fixing
+I: 522, 536
N: cjgohlke
E: cjgohlke@gmail.com
@@ -162,3 +170,141 @@
N: Jan Beich
E: jbeich@tormail.org
I: 325
+
+N: floppymaster
+E: floppymaster@gmail.com
+I: 380
+
+N: Arfrever.FTA
+E: Arfrever.FTA@gmail.com
+I: 369, 404
+
+N: danudey
+E: danudey@gmail.com
+I: 386
+
+N: Adrien Fallou
+I: 224
+
+N: Gisle Vanem
+E: gisle.vanem@gmail.com
+I: 411
+
+N: thepyr0
+E: thepyr0@gmail.com
+I: 414
+
+N: John Pankov
+E: john.pankov@gmail.com
+I: 435
+
+N: Matt Good
+I: 438
+
+N: Ulrich Klank
+E: ulrich.klank@scitics.de
+I: 448
+
+N: Josiah Carlson
+E: josiah.carlson@gmail.com
+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: crusaderky@gmail.com
+I: 470, 477
+
+E: alex@mroja.net
+I: 471
+
+N: Gautam Singh
+E: gautam.singh@gmail.com
+I: 466
+
+E: lhn@hupfeldtit.dk
+I: 476, 479
+
+N: Francois Charron
+E: francois.charron.1@gmail.com
+I: 474
+
+N: Naveed Roudsari
+E: naveed.roudsari@gmail.com
+I: 421
+
+N: Alexander Grothe
+E: Alexander.Grothe@gmail.com
+I: 497
+
+N: Szigeti Gabor Niif
+E: szigeti.gabor.niif@gmail.com
+I: 446
+
+N: msabramo
+E: msabramo@gmail.com
+I: 492
+
+N: Jeff Tang
+I: 340, 529, 616
+
+N: Yaolong Huang
+E: airekans@gmail.com
+I: 530
+
+N: Anders Chrigström
+I: 496
+
+N: spacewander
+E: spacewanderlzx@gmail.com
+I: 561
+
+N: Sylvain Mouquet
+E: sylvain.mouquet@gmail.com
+I: 565
+
+N: karthikrev
+I: 568
+
+N: Bruno Binet
+E: bruno.binet@gmail.com
+I: 572
+
+N: Gabi Davar
+C: Israel
+I: 578, 581, 587
+
+N: spacewanderlzx
+C: Guangzhou,China
+E: spacewanderlzx@gmail.com
+I: 555
+
+N: Fabian Groffen
+I: 611, 618
+
+N: desbma
+C: France
+I: 628
+
+N: John Burnett
+C: Irvine, CA, US
+I: 614
+
+N: Árni Már Jónsson
+E: Reykjavik, Iceland
+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);
+ '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();
+ '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':
+ document.cookie = 'sidebar=expanded';
+ }
+
+ function add_sidebar_button() {
+ 'float': 'left',
+ 'margin-right': '0',
+ 'width': ssb_width_expanded - 28
+ });
+ // create the button
+ '<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();
+ 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'));
+ '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
+ });
+
+ 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 @@
+{#
+ ~~~~~~~~~~~~~~~~~~~~
+
+ 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!)
+ 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() {
+ 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;
+}
+
+ 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%;
+}
+
+ 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;
+}
+
+ border-radius: 3px;
+}
+
+div.body div.impl-detail > p {
+ margin: 0;
+}
+
+ 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;
+}
+
+ font-size: 120%;
+}
+
+ font-weight: normal;
+}
+
+p.deprecated {
+ border-radius: 3px;
+}
+
+ 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():
+ 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',
+
+# 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' <grodola@gmail.com>
+
+.. warning::
+
+ This documentation refers to new 2.X version of psutil.
+ Instructions on how to port existing 1.2.1 code are
+ 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
+ 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.
+ 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``.
+ 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
+ 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
+ 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
+ See
+ 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.
+ 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.
+ 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
+ to obtain a usable socket object.
+ - **family**: the address family, either `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
+ `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
+ 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
+ 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
+ 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
+ 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
+ and
+ (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>`__
+ 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
+ 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
+ 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*).
+ 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
+ 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
+ `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
+ `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
+ It starts a sub process and deals with it exactly as when using
+ 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::
+
+ 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
+
+ >>> 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/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):
@@ -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(" 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' <g.rodola@gmail.com>
"""
-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 @@
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
+
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 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):
+ # >>> 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)
- laddr,
- raddr,
- str(c.status),
- p.pid,
- name[:15]))
+ 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 % (
+ 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 g.rodola@gmail.com $
#
-# 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' <g.rodola@gmail.com>
+
+$ 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 @@
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" \
- )
-
+ print_line("total packets: sent: %-10s received: %s" % (
# 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]))
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' <g.rodola@gmail.com>
+
+$ 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')
+
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']:
if pinfo['threads']:
print_('running threads', '')
for thread in pinfo['threads']:
- print_('', 'id=%s, user-time=%s, sys-time=%s' \
- if pinfo['connections'] != ACCESS_DENIED:
+ print_('', 'id=%s, user-time=%s, sys-time=%s' % (
+ 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:
+ 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' <g.rodola@gmail.com>
+
+$ 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 @@
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:
- 'get_memory_percent', 'get_cpu_percent',
- 'get_cpu_times', 'name', 'status'])
+ '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
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."""
@@ -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 rsesek@google.com)
- * #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.
- 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
+ jtang@vahna.net)
+- #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
+ alex@mroja.net)
+- #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() |
+ +--------------------------+----------------------+
+ +--------------------------+----------------------+
+
+- 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.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 rsesek@google.com)
+- #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.
+ 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:
+
+===================
+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 ("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 ==========================================================================
+
+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 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 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 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.
+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:
+ 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)" % (
+ elif 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):
+ 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):
+
+
+# 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()
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:
# 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) \
+ # 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
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 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 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 @@
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:
+ 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
- # 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
- 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 = _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 == \
- 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:
+ 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:
- 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._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
+ if _POSIX:
+ self._send_signal(signal.SIGSTOP)
else:
- # posix
@_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
+ if _POSIX:
+ self._send_signal(signal.SIGCONT)
else:
- # posix
+ @_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().
"""
+ 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':
+ whether PID has been reused.
+ """
+ if _POSIX:
+ self._send_signal(signal.SIGKILL)
else:
+ 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
+
+ For a complete documentation refer to:
"""
def __init__(self, *args, **kwargs):
+ # Explicitly avoid to raise NoSuchProcess in case the process
+ # spawned by subprocess.Popen terminates too quickly, see:
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:
- 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:
+ # 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()
-
-@_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
-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:
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:
- "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:
- "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'])
+sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
+ 'read_bytes', 'write_bytes',
+ 'read_time', 'write_time'])
+sdiskpart = namedtuple('sdiskpart', ['device', 'mountpoint', 'fstype', 'opts'])
+snetio = namedtuple('snetio', ['bytes_sent', 'bytes_recv',
+ 'packets_sent', 'packets_recv',
+ 'errin', 'errout',
+ 'dropin', 'dropout'])
+# psutil.users()
+suser = namedtuple('suser', ['name', 'terminal', 'host', 'started'])
+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
+
+pmem = namedtuple('pmem', ['rss', 'vms'])
+pcputimes = namedtuple('pcputimes', ['user', 'system'])
+popenfile = namedtuple('popenfile', ['path', 'fd'])
+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'])
+pio = namedtuple('pio', ['read_count', 'write_count',
+ 'read_bytes', 'write_bytes'])
+pionice = namedtuple('pionice', ['ioclass', 'value'])
+pctxsw = namedtuple('pctxsw', ['voluntary', 'involuntary'])
+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
-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):
- def setter(self, method):
-
- def deleter(self, method):
-
-
-# py 2.5 collections.defauldict
-# Taken from:
-# 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:
+ """
+ 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:
- 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):
- 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):
- 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 = {
+}
+
+TCP_STATUSES = {
+}
+
+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:
-# 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:
+ # 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:
+ # 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)
- 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):
@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,
+ 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>>
+ 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:
- # 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
+}
+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')
-_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:
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:
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
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:
+ # 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.
+
+ """
+
+ 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 (
+ 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:
+ """
+ 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:
+ 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)
+ if sys.byteorder == 'little':
+ ip = socket.inet_ntop(
+ struct.pack('>4I', *struct.unpack('<4I', ip)))
+ else:
+ ip = socket.inet_ntop(
+ 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:
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]
+ 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]
- raise NoSuchProcess(self.pid, self._process_name)
+ raise NoSuchProcess(self.pid, self._name)
- 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):
- try:
- name = f.read().split(' ')[1].replace('(', '').replace(')', '')
- finally:
- f.close()
+ def name(self):
+ 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:
- except (OSError, IOError):
- err = sys.exc_info()[1]
- if err.errno == errno.ENOENT:
+ except (OSError, IOError) as err:
# 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" % 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)
- 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):
- try:
- # return the args as a list
- return [x for x in f.read().split('\x00') if x]
- finally:
- f.close()
+ def cmdline(self):
+ 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()
- try:
- tty_nr = int(f.read().split(' ')[6])
- finally:
- f.close()
+ 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):
- 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()
-
- def get_process_io_counters(self):
- raise NotImplementedError("couldn't find /proc/%s/io (kernel " \
+ @wrap_exceptions
+ def io_counters(self):
+ 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):
- try:
+ def cpu_times(self):
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):
- try:
+ def create_time(self):
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):
- try:
+ def memory_info(self):
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 | |
# ============================================================
- try:
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:
- 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]
- raise NoSuchProcess(self.pid, self._process_name)
- raise AccessDenied(self.pid, self._process_name)
- raise
- except:
- if f is not None:
- f.close()
- raise
- f.close()
- 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
+ """
+ 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
- try:
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):
- try:
+ def num_threads(self):
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):
retlist = []
hit_enoent = False
for thread_id in thread_ids:
try:
- 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):
- #try:
+ def nice_get(self):
# 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:
+ # I saw this happening on Travis:
+ raise ZombieProcess(self.pid, self._name, self._ppid)
+ else:
+ raise
@wrap_exceptions
- def get_process_status(self):
- try:
+ def status(self):
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 = []
hit_enoent = False
for fd in files:
- 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
+ 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
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:
- 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.
- try:
- 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]
- 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
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):
+ def num_fds(self):
@wrap_exceptions
- def get_process_ppid(self):
- try:
+ def ppid(self):
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):
- try:
+ def uids(self):
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):
- try:
+ def gids(self):
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:
- """
- 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:
- 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)
- 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:
- 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."""
-
- @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:
- except OSError:
- err = sys.exc_info()[1]
- if err.errno in ACCESS_DENIED_SET:
- 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:
- except OSError:
- # XXX - can't use wrap_exceptions decorator as we're
- # returning a generator; probably needs refactoring.
- err = sys.exc_info()[1]
- 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'
-
- @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:
- except OSError:
- err = sys.exc_info()[1]
- if err.errno in ACCESS_DENIED_SET:
- raise
-
- @wrap_exceptions
- def get_process_num_threads(self):
-
- @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:
- except OSError:
- err = sys.exc_info()[1]
- if err.errno in ACCESS_DENIED_SET:
- 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):
-
- @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):
-
- @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:
- except OSError:
- err = sys.exc_info()[1]
- if err.errno in ACCESS_DENIED_SET:
- 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:
- except OSError:
- err = sys.exc_info()[1]
- if err.errno in ACCESS_DENIED_SET:
- 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')
+TCP_STATUSES = {
+}
-# --- functions
+PROC_STATUSES = {
+}
-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)
- 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):
@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:
+ 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)
@@ -104,7 +139,8 @@
# NB: the percentage is -5% than what shown by df due to
# reserved blocks that we are currently not considering:
- 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.SONPROC: _common.STATUS_RUNNING, # same as run
+}
+
+TCP_STATUSES = {
+ 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:
+ # ...nevertheless I can't manage to obtain the same numbers as 'swap'
+ # cmdline utility, so let's parse its output (sigh!)
+ 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 not pid_exists(self.pid):
+ raise NoSuchProcess(self.pid, self._name)
+ else:
+ raise ZombieProcess(self.pid, self._name, self._ppid)
+ 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 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:
+ 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
+
+ @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:
+ except OSError as err:
+ if err.errno == errno.ENOENT:
+ 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 = []
+ 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
+ return ret
+
+ @wrap_exceptions
+ def open_files(self):
+ retlist = []
+ hit_enoent = False
+ 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
+ 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:
+
+ # 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:
+ 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
+ hit_enoent = True
+ else:
+ raise
+ retlist.append((addr, perm, name, rss, anon, locked))
+ if hit_enoent:
+ # raise NSP if the process disappeared on us
+ return retlist
+
+ @wrap_exceptions
+ def num_fds(self):
+
+ @wrap_exceptions
+ def num_ctx_switches(self):
+
+ @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:
*/
-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,
+ return Py_BuildValue("(ll)",
}
-
/*
* 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:
+ * 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,
- -1, -1);
+ return Py_BuildValue("(llll)",
+ -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:
*/
-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:
- */
-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:
+ // 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",
- 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:
+// 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.
+ */
+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.
+ */
+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:
+#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:
*/
-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:
+ */
+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:
-
- 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) {
- 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
- */
-
- 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;
-
- 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)",
- (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)",
- 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:
-#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,
- 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",
- (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,
-}
-
-
-/*
- * 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
-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)",
- * 10) / 1000,
- * 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
- 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,
- );
- 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:
// 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",
- (unsigned long long)vmstat.pageins * pagesize,
- (unsigned long long)vmstat.pageouts * pagesize);
+ return Py_BuildValue(
+ "LLLKK",
+ (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
*/
-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)",
+ (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:
- */
-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
*/
-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,
lip,
sizeof(lip));
inet_ntop(AF_INET,
rip,
sizeof(rip));
}
else {
inet_ntop(AF_INET6,
lip, sizeof(lip));
inet_ntop(AF_INET6,
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,
- "");
+ 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:
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:
+ // 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:
+ */
+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:
+#undef _FILE_OFFSET_BITS
+#define _STRUCTURED_PROC 1
+
+// fix compilation issue on SunOS 5.10, see:
+#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",
+}
+
+
+/*
+ * 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:
+ * ...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_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:
+// 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:
+ * ...and:
+ */
+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:
+ 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:
+ */
+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
+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:
+
+ 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) \
+ 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) {
+ 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;
+
+ 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:
+ // 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,
+ 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",
+ (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)",
+}
+
+
+/*
+ * 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)",
+ (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
+ 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,
+ 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
+ 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,
+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_DELETE_TCB: CONN_DELETE_TCB,
+}
+
+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:
+
+ 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:
+ # 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))
+ 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:
-#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
- * 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,
- 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",
- 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",
- objectTypeInfo->Name.Length / 2,
- objectTypeInfo->Name.Buffer,
- objectName.Length / 2,
- );
- */
- }
- else
- {
- /* Print something else. */
- /*
- printf(
- "[%#x] %.*S: (unnamed)\n",
- 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;
-}
-
-
-/*
- *
- * 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:
+#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
+ * 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,
+ );
+ */
+ }
+ 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;
+}
+
+
+/*
+ *
+ * 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:
-"""
-
-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
->>> p.getcwd()
->>> 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
+
+ :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
+====================
+
+ :alt: top
+
+ :alt: nettop
+
+ :alt: iotop
+
+See also:
+
+
+==============
+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.
+
+ :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
+============
+
+
+========
+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():
- '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():
- 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',
- 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',
+ ],
+ define_macros=[
+ VERSION_MACRO,
+ # be nice to mingw, see:
+ ('_WIN32_WINNT', get_winver()),
+ ('_AVAIL_WINVER_', get_winver()),
+ ('_CRT_SECURE_NO_WARNINGS', None),
+ ('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',
- extra_link_args=['-framework', 'CoreFoundation',
- '-framework', 'IOKit']
- ),
- posix_extension]
+ extensions = [Extension(
+ 'psutil._psutil_osx',
+ sources=[
+ 'psutil/_psutil_osx.c',
+ 'psutil/_psutil_common.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',
- libraries=["devstat"],
- ),
- posix_extension]
+ extensions = [Extension(
+ 'psutil._psutil_bsd',
+ sources=[
+ 'psutil/_psutil_bsd.c',
+ 'psutil/_psutil_common.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='psutil@googlegroups.com',
- 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])
+@unittest.skipUnless(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)
+ out.split('\n')[1].split()[-1])
+
+ def test_cmdline(self):
+ out = sh('procstat -c %s' % self.pid)
+ ' '.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')
+ 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')
+ 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]
+@unittest.skipUnless(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]
+ "'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]
+ "'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:
+ 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:
+ assert m.called
+
+ def test_proc_terminal_mocked(self):
+ with mock.patch('psutil._pslinux._psposix._get_terminal_map',
+ return_value={}) as m:
+ assert m.called
+
+ def test_proc_num_ctx_switches_mocked(self):
+ with mock.patch('psutil._pslinux.open', create=True) as m:
+ 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:
+ 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:
+ 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:
+ 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:
+ NotImplementedError,
+ psutil._pslinux.Process(os.getpid()).gids)
+ assert m.called
+
+ # --- tests for specific kernel versions
+
+ 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())
+ # 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"))
+
+ 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
+@unittest.skipUnless(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
+@unittest.skipUnless(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_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_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()
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_psutil = psutil.get_pid_list()
+ pids_psutil = psutil.pids()
@@ -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():
+ 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
+
+
+@unittest.skipUnless(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
+@unittest.skipUnless(WINDOWS, "not a Windows system")
class WindowsSpecificTestCase(unittest.TestCase):
- def setUp(self):
- sproc = get_test_subprocess()
- wait_for_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)
- 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)
@@ -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:
except psutil.Error:
pass
- if wmi is not None:
-
- # --- Process class tests
+ # --- Process class tests
- def test_process_name(self):
- p = psutil.Process(self.pid)
-
- def test_process_exe(self):
- p = psutil.Process(self.pid)
-
- def test_process_cmdline(self):
- p = psutil.Process(self.pid)
-
- def test_process_username(self):
- 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)
- 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)
- 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):
- p = psutil.Process(self.pid)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- 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]
-
- 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.
- p = psutil.Process(0)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- # 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
- 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):
+ p = psutil.Process(self.pid)
- if win32api is not None:
+ @unittest.skipIf(wmi is None, "wmi module is not installed")
+ def test_process_exe(self):
+ p = psutil.Process(self.pid)
+ # Note: wmi reports the exe as a lower case string.
+ # Being Windows paths case-insensitive we ignore that.
+
+ @unittest.skipIf(wmi is None, "wmi module is not installed")
+ def test_process_cmdline(self):
+ 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()
- 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):
+ 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)
+ 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)
+ 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):
+ 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]
+ 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.
+ # 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
+ 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()
+ 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
+@unittest.skipUnless(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:
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:
+ 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:
--- 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
+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):
@@ -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 @@
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 @@
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):
+ self.execute('cpu_count')
+
+ @skip_if_linux()
+ def test_cpu_count_physical(self):
+ 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')
+
+ '/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:
- 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
-to use 2to3 tool first.
+If you're on Python < 2.7 unittest2 module must be installed first:
"""
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'))
+
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)
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:
+ 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):
- 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.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:
+ 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)
+
+ if getattr(conn, 'fd', -1) != -1:
+ assert conn.fd > 0, conn
+ if hasattr(socket, 'fromfd') and not WINDOWS:
+ try:
+ 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.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:
+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 @@
-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):
sproc = get_test_subprocess()
p = psutil.Process(sproc.pid)
p.kill()
p.wait()
- 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):
- 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):
+
+ def test_wait_procs(self):
+ def callback(p):
+
+ 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)
+ if POSIX:
else:
-
- def test_NUM_CPUS(self):
- 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)
+ 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
- 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:
- finally:
-
- def test_deprecated_apis_retval(self):
- warnings.filterwarnings("ignore")
- p = psutil.Process(os.getpid())
- try:
- finally:
-
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)
p = psutil.Process(sproc.pid)
p.kill()
p.wait()
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()
# 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:
+ 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:
+ 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)
+ 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 @@
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)),
- 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)),
- 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
+ delta=tolerance)
+ 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):
+ # XXX this test is not really reliable as it always fails on
+ 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:
+ 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:
- except OSError:
- err = sys.exc_info()[1]
+ except OSError as err:
+ # 2012-June/120787.html
raise
else:
- 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):
+ 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(
+ 0, socket.AI_PASSIVE)[0]
+ af, socktype, proto, canonname, sa = info
+ s = socket.socket(af, socktype, proto)
+ with contextlib.closing(s):
+ s.bind(sa)
+ 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"):
+ elif LINUX:
+ 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,
+ 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)
+
+ '/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:
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
@@ -659,40 +1087,55 @@
assert user.started > 0.0, user
- # ====================
- # 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):
+ sproc = get_test_subprocess()
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.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)
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()
# 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 @@
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)
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
@@ -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
- @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)
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))
+ 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))
+
+ 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()
try:
- step2 = p.get_num_threads()
+ step2 = p.num_threads()
self.assertEqual(step2, step1 + 1)
finally:
if thread._running:
- @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()
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:
- 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()
+ 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 @@
def test_cmdline(self):
- sproc = get_test_subprocess([PYTHON, "-E"], wait=True)
+ cmdline = [PYTHON, "-c", "import time; time.sleep(60)"]
+ sproc = get_test_subprocess(cmdline, wait=True)
+ ' '.join(cmdline))
def test_name(self):
sproc = get_test_subprocess(PYTHON, wait=True)
+ name = psutil.Process(sproc.pid).name().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:
+ 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 )")
+
+ @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)
+ finally:
+ 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:
- finally:
-
def test_status(self):
- p = psutil.Process(os.getpid())
- 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 == 'sleeping')
- self.assertFalse(psutil.STATUS_RUNNING != 'running')
- self.assertTrue(psutil.STATUS_RUNNING != 1)
- self.assertTrue(psutil.STATUS_RUNNING != 'sleeping')
+ p = psutil.Process()
def test_username(self):
sproc = get_test_subprocess()
p = psutil.Process(sproc.pid)
if POSIX:
import pwd
- elif WINDOWS:
+ 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()
- @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)
- @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)
- @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(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"):
+ 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"):
+ 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()
-
- 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.status, "LISTEN")
- ip, port = con.local_address
- self.assertEqual(ip, '127.0.0.1')
- 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.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.bind(TESTFN)
- conn = psutil.Process(os.getpid()).get_connections(kind='unix')[0]
- self.assertEqual(conn.local_address, TESTFN)
- self.assertTrue(not conn.status)
- sock.close()
- # udp
- safe_remove(TESTFN)
- sock.bind(TESTFN)
- conn = psutil.Process(os.getpid()).get_connections(kind='unix')[0]
- 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")
- try:
- 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
+
+ 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.local_address[0], "127.0.0.1")
- 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, (),
+ ("all", "inet", "inet4", "tcp", "tcp4"))
# UDP v4
elif p.pid == udp4_proc.pid:
- self.assertEqual(conn.local_address[0], "127.0.0.1")
- 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, (),
+ ("all", "inet", "inet4", "udp", "udp4"))
# TCP v6
elif p.pid == getattr(tcp6_proc, "pid", None):
- self.assertIn(conn.local_address[0], ("::", "::1"))
- 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, (),
+ ("all", "inet", "inet6", "tcp", "tcp6"))
# UDP v6
elif p.pid == getattr(udp6_proc, "pid", None):
- self.assertIn(conn.local_address[0], ("::", "::1"))
- 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, (),
+ ("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.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")
+ with contextlib.closing(dupsock):
+
+ 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:
+ if WINDOWS:
- @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.assertEqual(p.num_fds(), start + 1)
sock = socket.socket()
- self.assertEqual(p.get_num_fds(), start + 2)
+ self.assertEqual(p.num_fds(), start + 2)
- 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():
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)
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()
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:
- except psutil.NoSuchProcess:
- pass
- else:
- self.fail("exception not raised")
- if hasattr(p, 'set_ionice'):
- if hasattr(p, "set_cpu_affinity"):
- 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)
+ 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
+ # ...and it should be considered '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.
+ # ...and all other APIs should be able to deal with it
+ self.assertTrue(psutil.pid_exists(zpid))
+ self.assertIn(zpid, psutil.pids())
+ psutil._pmap = {}
+ 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():
+ return
+
p = psutil.Process(0)
+ 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.num_threads()
except psutil.AccessDenied:
pass
try:
+ 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:
+ 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())
- 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);"]
+ cmd = [PYTHON, "-c", "import time; time.sleep(60);"]
+ proc = psutil.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
try:
+ proc.name()
self.assertTrue(hasattr(proc, 'name'))
self.assertTrue(hasattr(proc, 'stdin'))
@@ -1666,18 +2228,17 @@
finally:
-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:
if err.name:
# make sure exception's name attr is set
# with the actual process name
self.assertTrue(str(err))
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())
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:
- 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
@@ -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:
- 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.bind((conn.local_address[0], 0))
- s.close()
+ check_connection_ntuple(conn)
- if not WINDOWS and hasattr(socket, 'fromfd'):
- dupsock = None
- try:
- try:
- except (socket.error, OSError):
- err = sys.exc_info()[1]
- if err.args[0] == errno.EBADF:
- continue
- raise
- # python >= 2.5
- if hasattr(dupsock, "family"):
- 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:
- 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('['):
- # commented as on Linux we might get '/foo/bar (deleted)'
+ # commented as on Linux we might get
+ # '/foo/bar (deleted)'
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)
-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
+# ===================================================================
+
+@unittest.skipUnless(POSIX, "UNIX only")
+@unittest.skipUnless(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):
- 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):
+ 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__))
+ 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):
-atexit.register(cleanup)
-safe_remove(TESTFN)
+ def test_free(self):
+
+ def test_meminfo(self):
+
+ def test_process_detail(self):
+
+ 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):
+
+ def test_netstat(self):
+
+ @unittest.skipIf(TRAVIS, "permission denied on travis")
+ def test_ifconfig(self):
+
+ def test_pmap(self):
+
+ @unittest.skipIf(ast is None,
+ 'ast module not available on this python version')
+ def test_killall(self):
+
+ @unittest.skipIf(ast is None,
+ 'ast module not available on this python version')
+ def test_nettop(self):
+
+ @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):
+
+ def test_pidof(self):
+ 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:
+
+
+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:
+
+ * 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:
+
+ * 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/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 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