diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-13 01:42:48 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-13 01:42:48 +0000 |
commit | 041d14a0ce223d741c5b7224ed356ced412402e2 (patch) | |
tree | 7a0ae6ee80b2df261098ae87dc6ef10cf359b584 /third_party | |
parent | f517b3f8dfef01ca05d061859f839257c578e857 (diff) | |
download | chromium_src-041d14a0ce223d741c5b7224ed356ced412402e2.zip chromium_src-041d14a0ce223d741c5b7224ed356ced412402e2.tar.gz chromium_src-041d14a0ce223d741c5b7224ed356ced412402e2.tar.bz2 |
Remove psutil from tree, install via install-build-deps.sh
Per discussion with thakis, cmp we should remove this dep from the tree and instead install it via install-build-deps.sh.
BUG=106105
TEST=Installed dep, ran tests.
Review URL: http://codereview.chromium.org/8919026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114146 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
57 files changed, 0 insertions, 14822 deletions
diff --git a/third_party/psutil/CREDITS b/third_party/psutil/CREDITS deleted file mode 100644 index b39f05b..0000000 --- a/third_party/psutil/CREDITS +++ /dev/null @@ -1,72 +0,0 @@ - -Intro -===== - -We 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 -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). -Really thanks to all of you. - - -Maintainers -=========== - -N: Giampaolo Rodola' -C: Italy -E: g.rodola@gmail.com - -N: Jay Loden -C: NJ, USA -E: jloden@gmail.com -W: http://www.jayloden.com - - -Contributors -============ - -N: Jeremy Whitlock -E: jcscoobyrs@gmail.com -I: 125, 150, 174, 206 - -N: wj32 -E: wj32.64@gmail.com -D: process username() and get_connections() on Windows -I: 114, 115 - -N: Yan Raber -C: Bologna, Italy -E: yanraber@gmail.com -D: help on Windows development - -N: Dave Daeschler -C: USA -E: ddaeschl@rsaisp.com - -N: cjgohlke -E: cjgohlke@gmail.com -D: Windows 64 bit support -I: 107 - -N: Jeffery Kline -E: jeffery.kline@gmail.com -I: 130 - -N: Grabriel Monnerat -E: gabrielmonnerat@gmail.com -I: 146 - -N: Philip Roberts -E: philip.roberts@gmail.com -I: 168 - -N: jcscoobyrs -E: jcscoobyrs@gmail.com -I: 125 - -N: Sandro Tosi -E: sandro.tosi@gmail.com -I: 200, 201 diff --git a/third_party/psutil/HISTORY b/third_party/psutil/HISTORY deleted file mode 100644 index 40ea22e..0000000 --- a/third_party/psutil/HISTORY +++ /dev/null @@ -1,247 +0,0 @@ -Bug tracker at http://code.google.com/p/psutil/issues - -0.3.1 - XXXX-XX-XX ------------------- - -NEW FEATURES - - * Issue 150: network I/O counters. (OSX patch by Jeremy Whitlock) - * Issue 198: Process.wait(timeout=0) can now be used to make wait() return - immediately. - * Issue 206: disk I/O counters. (OSX patch by Jeremy Whitlock) - -BUGFIXES - - * Issue 135: (OS X) psutil cannot create Process object - * Issue 144: (Linux) no longer support 0 special PID. - * Issue 188: (Linux) psutil import error on Linux ARM architectures. - * Issue 197: (Linux) Process.get_connections() is broken on platforms not - supporting IPv6. - * Issue 200: (Linux) psutil.NUM_CPUS not working on armel and sparc - architectures and causing crash on module import. - * Issue 201: (Linux) Process.get_connections() is broken on big-endian - architectures. - * Issue 211: Process instance can unexpectedly raise NoSuchProcess if tested - for equality with another object. - - -0.3.0 - 2011-07-08 ------------------- - -NEW FEATURES - - * Issue 125: system per-cpu percentage utilization and times. - * Issue 163: per-process associated terminal (TTY). - * Issue 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. - * Issue 172: disk usage statistics. - * Issue 174: mounted disk partitions. - * Issue 179: setuptools is now used in setup.py - -BUGFIXES - - * Issue 159: SetSeDebug() does not close handles or unset impersonation on - return. - * Issue 164: wait function raises a TimeoutException when a process returns - -1 (Windows). - * Issue 165: process.status raises an unhandled exception. - * Issue 166: get_memory_info() leaks handles hogging system resources. - * Issue 168: psutil.cpu_percent() returns erroneous results when used in - non-blocking mode. (patch by Philip Roberts) - * Issue 178: OSX - Process.get_threads() leaks memory - * Issue 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 - - * Issue 64: per-process I/O counters. - * Issue 116: per-process wait() (wait for process to terminate and return its - exit code). - * Issue 134: per-process get_threads() returning information (id, user and - kernel times) about threads opened by process. - * Issue 136: process executable path on FreeBSD is now determined by asking - the kernel instead of guessing it from cmdline[0]. - * Issue 137: per-process real, effective and saved user and group ids. - * Issue 140: system boot time. - * Issue 142: per-process get and set niceness (priority). - * Issue 143: per-process status. - * Issue 147: per-process I/O nice (priority) - Linux only. - * Issue 148: psutil.Popen class which tidies up subprocess.Popen and - psutil.Process in a unique interface. - * Issue 152: (OSX) get_process_open_files() implementation has been rewritten - in C and no longer relies on lsof resulting in a 3x speedup. - * Issue 153: (OSX) get_process_connection() implementation has been rewritten - in C and no longer relies on lsof resulting in a 3x speedup. - -BUGFIXES - - * Issue 83: process cmdline is empty on OSX 64-bit. - * Issue 130: a race condition can cause IOError exception be raised on - Linux if process disappears between open() and subsequent read() calls. - * Issue 145: WindowsError was raised instead of psutil.AccessDenied when using - process resume() or suspend() on Windows. - * Issue 146: 'exe' property on Linux can raise TypeError if path contains NULL - bytes. - * Issue 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 - - * Issue 79: per-process open files. - * Issue 88: total system physical cached memory. - * Issue 88: total system physical memory buffers used by the kernel. - * Issue 91: per-process send_signal() and terminate() methods. - * Issue 95: NoSuchProcess and AccessDenied exception classes now provide "pid", - "name" and "msg" attributes. - * Issue 97: per-process children. - * Issue 98: Process.get_cpu_times() and Process.get_memory_info now return - a namedtuple instead of a tuple. - * Issue 103: per-process opened TCP and UDP connections. - * Issue 107: add support for Windows 64 bit. (patch by cjgohlke) - * Issue 111: per-process executable name. - * Issue 113: exception messages now include process name and pid. - * Issue 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) - * Issue 117: added support for Windows 2000. - * Issue 123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a - new 'interval' parameter. - * Issue 129: per-process number of threads. - -BUGFIXES - - * Issue 80: fixed warnings when installing psutil with easy_install. - * Issue 81: psutil fails to compile with Visual Studio. - * Issue 94: suspend() raises OSError instead of AccessDenied. - * Issue 86: psutil didn't compile against FreeBSD 6.x. - * Issue 102: orphaned process handles obtained by using OpenProcess in C were - left behind every time Process class was instantiated. - * Issue 111: path and name Process properties report truncated or erroneous - values on UNIX. - * Issue 120: cpu_percent() always returning 100% on OS X. - * Issue 112: uid and gid properties don't change if process changes effective - user/group id at some point. - * Issue 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 - - * Issue 14: per-process username - * Issue 51: per-process current working directory (Windows and Linux only) - * Issue 59: Process.is_running() is now 10 times faster - * Issue 61: added supoprt for FreeBSD 64 bit - * Issue 71: implemented suspend/resume process - * Issue 75: python 3 support - -BUGFIXES - - * Issue 36: process cpu_times() and memory_info() functions succeeded also for - dead processes while a NoSuchProcess exception is supposed to be raised. - * Issue 48: incorrect size for mib array defined in getcmdargs for BSD - * Issue 49: possible memory leak due to missing free() on error condition on - * Issue 50: fixed getcmdargs() memory fragmentation on BSD - * Issue 55: test_pid_4 was failing on Windows Vista - * Issue 57: some unit tests were failing on systems where no swap memory is - available - * Issue 58: is_running() is now called before kill() to make sure we are going - to kill the correct process. - * Issue 73: virtual memory size reported on OS X includes shared library size - * Issue 77: NoSuchProcess wasn't raised on Process.create_time if kill() was - used first. - - -0.1.2 - 2009-05-06 ------------------- - -NEW FEATURES - - * Issue 32: Per-process CPU user/kernel times - * Issue 33: Process create time - * Issue 34: Per-process CPU utilization percentage - * Issue 38: Per-process memory usage (bytes) - * Issue 41: Per-process memory utilization (percent) - * Issue 39: System uptime - * Issue 43: Total system virtual memory - * Issue 46: Total system physical memory - * Issue 44: Total system used/free virtual and physical memory - -BUGFIXES - - * Issue 36: NoSuchProcess not raised on Windows when accessing timing methods - * Issue 40: test_get_cpu_times() failing on FreeBSD and OS X - * Issue 42: get_memory_percent() raises AccessDenied on Windows - - -0.1.1 - 2009-03-06 ------------------- - -NEW FEATURES - - * Issue 4: FreeBSD support for all functions of psutil - * Issue 9: Process.uid and Process.gid now retrieve process UID and GID. - * Issue 11: Support for parent/ppid - Process.parent property returns a - Process object representing the parent process, and Process.ppid returns - the parent PID. - * Issue 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. - * Issue 21: AccessDenied exception created for raising access denied errors - from OSError or WindowsError on individual platforms. - * Issue 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 - - * Issue 16: Special case for Windows' "System Idle Process" (PID 0) which - otherwise would return an "invalid parameter" exception. - * Issue 17: get_process_list() ignores NoSuchProcess and AccessDenied - exceptions during building of the list. - * Issue 22: Process(0).kill() was failing on Windows with an unset exception - * Issue 23: Special case for pid_exists(0) - * Issue 24: Process(0).kill() now raises AccessDenied exception instead of - WindowsError. - * Issue 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. - diff --git a/third_party/psutil/LICENSE b/third_party/psutil/LICENSE deleted file mode 100644 index e91b135..0000000 --- a/third_party/psutil/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -psutil is distributed under BSD license reproduced below. - -Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola' -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the psutil authors nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/psutil/MANIFEST.in b/third_party/psutil/MANIFEST.in deleted file mode 100644 index 2018576..0000000 --- a/third_party/psutil/MANIFEST.in +++ /dev/null @@ -1,10 +0,0 @@ -include CREDITS -include HISTORY -include LICENSE -include MANIFEST.in -include README -include setup.py -recursive-include docs *.html *.dia *.png -recursive-include psutil *.py *.c *.h -recursive-include test *.py -recursive-include examples *.py diff --git a/third_party/psutil/PKG-INFO b/third_party/psutil/PKG-INFO deleted file mode 100644 index 1b6f134..0000000 --- a/third_party/psutil/PKG-INFO +++ /dev/null @@ -1,40 +0,0 @@ -Metadata-Version: 1.0 -Name: psutil -Version: 0.2.0 -Summary: A process utilities module for Python -Home-page: http://code.google.com/p/psutil/ -Author: Giampaolo Rodola, Dave Daeschler, Jay Loden -Author-email: psutil-dev@googlegroups.com -License: License :: OSI Approved :: BSD License -Description: - psutil is a module providing convenience functions for managing processes in a - portable way by using Python. -Keywords: psutil,ps,top,process,utility -Platform: Platform Independent -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Console -Classifier: Operating System :: MacOS :: MacOS X -Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000 -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: Topic :: System :: Monitoring -Classifier: Topic :: System :: Networking -Classifier: Topic :: System :: Benchmark -Classifier: Topic :: System :: Systems Administration -Classifier: Topic :: Utilities -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: System Administrators -Classifier: License :: OSI Approved :: MIT License diff --git a/third_party/psutil/README b/third_party/psutil/README deleted file mode 100644 index 18ca454..0000000 --- a/third_party/psutil/README +++ /dev/null @@ -1,120 +0,0 @@ - -Introduction -============ - -psutil is a module providing an interface for retrieving information on running -processes in a portable way by using Python. -It currently supports Linux, OS X, FreeBSD and Windows. - -psutil website is at http://code.google.com/p/psutil/ - -The following document describes how to compile and install psutil from sources -on different platforms. - - -Using easy_install -================== - -The easiest way to install psutil from sources is using easy_install. -Get the latest easy_install version from http://pypi.python.org/pypi/setuptools -and just run: - - > easy_install psutil - -This should get the most updated psutil version from the Python pypi repository, -unpack it, compile it and install it automatically. - - -Installing on Windows using mingw32 -=================================== - -After the mingw [1] environment is properly set up on your system you can -compile Windows sources by entering: - - > setup.py build -c mingw32 - -To compile and install just append the "install" keyword at the end of the -command line above, like this: - - > setup.py build -c mingw32 install - -It might be possible that distutils will complain about missing gcc executable. -That means you have to add mingw bin PATH variable first. -Entering this line in the command prompt should do the work: - - > SET PATH=C:\MinGW\bin;%PATH% - -NOTE: this assumes MinGW is installed in C:\MinGW, if not simply replace the -path in the command above with an appropriate location. - -[1] http://www.mingw.org/ - - -Installing on Windows using Visual Studio -========================================= - -To use Visual Studio to install psutil, you must have the same version of -Visual Studio used to compile your installation of Python. For older versions -of Python that will be Visual Studio 2003. For 2.6 and later it should be -Visual Studio 2008. If you do not have the requisite version of Visual Studio -available then it is recommended to use MinGW to compile psutil instead. - -If you do have Visual Studio installed, you can use the basic distutils -commands: - - > setup.py build - -or to install and build: - - > setup.py install - -distutils should take care of any necessary magic to compile from there. - - -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 - -NOTE: due to developer's hardware limitations psutil has only been compiled and -tested on OS X 10.4.11 so may or may not work on other versions. - - -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 - - -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 Ubuntu: - - > sudo apt-get install python-dev - -Once done, you can install/build psutil with: - - > python setup.py install - diff --git a/third_party/psutil/README.chromium b/third_party/psutil/README.chromium deleted file mode 100644 index 7e0dd2f..0000000 --- a/third_party/psutil/README.chromium +++ /dev/null @@ -1,17 +0,0 @@ -Name: Python process utilities -Short Name: psutil -URL: http://code.google.com/p/psutil/ -Version: 0.3.1 -License: BSD -License File: LICENSE -Security Critical: Yes - -Description: -psutil is a module providing an interface for retrieving information -on running processes and system utilization (CPU, memory) in a portable -way by using Python, implementing many functionalities offered by -command line tools like ps, top, kill, lsof and netstat. - -Local Modifications: -None - diff --git a/third_party/psutil/docs/BUILDING.txt b/third_party/psutil/docs/BUILDING.txt deleted file mode 100644 index 14dc8a1..0000000 --- a/third_party/psutil/docs/BUILDING.txt +++ /dev/null @@ -1,37 +0,0 @@ -_OS X_ -INSTALL FROM SOURCE - python setup.py install - - -CREATE AN INSTALLER PACKAGE - #NOTE: this requires bdist_mkpkg utility to create the binary installer - # http://pypi.python.org/pypi/bdist_mpkg/ - # - # --open opens the installer after build - bdist_mpkg --license LICENSE --readme HISTORY - - # build for older Python - /Library/Frameworks/Python.framework/Versions/2.5/bin/bdist_mpkg - - -CREATE A DMG OF THE INSTALLER - # fill in directory/filenames as appropriate for srcfolder, volname - # and the output dmg file - hdiutil create -fs HFS+ -srcfolder psutil-0.1.1-py2.6-macosx10.4.mpkg -volname psutil-0.1.1 psutil-0.1.1-py2.6-macosx10.4.dmg - - -UPLOAD TO GOOGLE CODE - # fill in summary and file name - googlecode_upload.py -s "Python 2.6 OS X Installer/Binary distribution" -p psutil dist/psutil-0.1.1-py2.6-macosx10.4.dmg - - -__WINDOWS__ -INSTALL FROM SOURCE - - # if Visual studio - python setup.py install - - # mingw - python setup.py build -c mingw32 - - diff --git a/third_party/psutil/docs/class_diagram.dia b/third_party/psutil/docs/class_diagram.dia deleted file mode 100644 index 401ac72..0000000 --- a/third_party/psutil/docs/class_diagram.dia +++ /dev/null @@ -1,1475 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/"> - <dia:diagramdata> - <dia:attribute name="background"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="pagebreak"> - <dia:color val="#000099"/> - </dia:attribute> - <dia:attribute name="paper"> - <dia:composite type="paper"> - <dia:attribute name="name"> - <dia:string>#A4#</dia:string> - </dia:attribute> - <dia:attribute name="tmargin"> - <dia:real val="2.8222000598907471"/> - </dia:attribute> - <dia:attribute name="bmargin"> - <dia:real val="2.8222000598907471"/> - </dia:attribute> - <dia:attribute name="lmargin"> - <dia:real val="2.8222000598907471"/> - </dia:attribute> - <dia:attribute name="rmargin"> - <dia:real val="2.8222000598907471"/> - </dia:attribute> - <dia:attribute name="is_portrait"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="scaling"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="fitto"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - <dia:attribute name="grid"> - <dia:composite type="grid"> - <dia:attribute name="width_x"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="width_y"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="visible_x"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="visible_y"> - <dia:int val="1"/> - </dia:attribute> - <dia:composite type="color"/> - </dia:composite> - </dia:attribute> - <dia:attribute name="color"> - <dia:color val="#d8e5e5"/> - </dia:attribute> - <dia:attribute name="guides"> - <dia:composite type="guides"> - <dia:attribute name="hguides"/> - <dia:attribute name="vguides"/> - </dia:composite> - </dia:attribute> - </dia:diagramdata> - <dia:layer name="Background" visible="true" active="true"> - <dia:object type="UML - LargePackage" version="0" id="O0"> - <dia:attribute name="obj_pos"> - <dia:point val="4.25,0.01251"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="4.2,-1.03749;61.8,36.5375"/> - </dia:attribute> - <dia:attribute name="meta"> - <dia:composite type="dict"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="4.25,0.01251"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="57.500000000000007"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="36.474989999999977"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.10000000000000001"/> - </dia:attribute> - <dia:attribute name="line_colour"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_colour"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_colour"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#psutil#</dia:string> - </dia:attribute> - </dia:object> - <dia:object type="UML - Class" version="0" id="O1"> - <dia:attribute name="obj_pos"> - <dia:point val="27.7475,4.05"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="27.6975,4;35.1975,6.2"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="27.7475,4.05"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="7.4000000000000004"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="2.0999999999999996"/> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#psutil (module)#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>#main py module#</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_comments"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_after_char"> - <dia:int val="40"/> - </dia:attribute> - <dia:attribute name="comment_line_length"> - <dia:int val="17"/> - </dia:attribute> - <dia:attribute name="comment_tagging"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.10000000000000001"/> - </dia:attribute> - <dia:attribute name="line_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_color"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="normal_font"> - <dia:font family="monospace" style="0" name="Courier"/> - </dia:attribute> - <dia:attribute name="abstract_font"> - <dia:font family="monospace" style="88" name="Courier-BoldOblique"/> - </dia:attribute> - <dia:attribute name="polymorphic_font"> - <dia:font family="monospace" style="8" name="Courier-Oblique"/> - </dia:attribute> - <dia:attribute name="classname_font"> - <dia:font family="sans" style="80" name="Helvetica-Bold"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font"> - <dia:font family="sans" style="88" name="Helvetica-BoldOblique"/> - </dia:attribute> - <dia:attribute name="comment_font"> - <dia:font family="sans" style="8" name="Helvetica-Oblique"/> - </dia:attribute> - <dia:attribute name="normal_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="polymorphic_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="abstract_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="comment_font_height"> - <dia:real val="0.69999999999999996"/> - </dia:attribute> - <dia:attribute name="attributes"/> - <dia:attribute name="operations"/> - <dia:attribute name="template"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="templates"/> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="UML - Class" version="0" id="O2"> - <dia:attribute name="obj_pos"> - <dia:point val="12.7,9.3"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="12.65,9.25;19.41,19.65"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="12.7,9.3"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="6.6600000000000001"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="10.300000000000001"/> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#Process class#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>#higher-level public python wrapper#</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_attributes"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_comments"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_after_char"> - <dia:int val="40"/> - </dia:attribute> - <dia:attribute name="comment_line_length"> - <dia:int val="17"/> - </dia:attribute> - <dia:attribute name="comment_tagging"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.10000000000000001"/> - </dia:attribute> - <dia:attribute name="line_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_color"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="normal_font"> - <dia:font family="monospace" style="0" name="Courier"/> - </dia:attribute> - <dia:attribute name="abstract_font"> - <dia:font family="monospace" style="88" name="Courier-BoldOblique"/> - </dia:attribute> - <dia:attribute name="polymorphic_font"> - <dia:font family="monospace" style="8" name="Courier-Oblique"/> - </dia:attribute> - <dia:attribute name="classname_font"> - <dia:font family="sans" style="80" name="Helvetica-Bold"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font"> - <dia:font family="sans" style="88" name="Helvetica-BoldOblique"/> - </dia:attribute> - <dia:attribute name="comment_font"> - <dia:font family="sans" style="8" name="Helvetica-Oblique"/> - </dia:attribute> - <dia:attribute name="normal_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="polymorphic_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="abstract_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="comment_font_height"> - <dia:real val="0.69999999999999996"/> - </dia:attribute> - <dia:attribute name="attributes"> - <dia:composite type="umlattribute"> - <dia:attribute name="name"> - <dia:string>#pid#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - <dia:composite type="umlattribute"> - <dia:attribute name="name"> - <dia:string>#name#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - <dia:composite type="umlattribute"> - <dia:attribute name="name"> - <dia:string>#cmdline#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - <dia:composite type="umlattribute"> - <dia:attribute name="name"> - <dia:string>#...#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - <dia:attribute name="operations"> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#get_cpu_times#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#terminate#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#kill#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#...#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - </dia:attribute> - <dia:attribute name="template"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="templates"> - <dia:composite type="umlformalparameter"> - <dia:attribute name="name"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - </dia:composite> - </dia:attribute> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="UML - Class" version="0" id="O3"> - <dia:attribute name="obj_pos"> - <dia:point val="24.85,16.25"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="24.8,16.2;36.4925,23.2"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="24.85,16.25"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="11.592499999999999"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="6.9000000000000004"/> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#_ps[platform].py module#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>#intermediate python wrapper module#</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_comments"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_after_char"> - <dia:int val="40"/> - </dia:attribute> - <dia:attribute name="comment_line_length"> - <dia:int val="17"/> - </dia:attribute> - <dia:attribute name="comment_tagging"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.10000000000000001"/> - </dia:attribute> - <dia:attribute name="line_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_color"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="normal_font"> - <dia:font family="monospace" style="0" name="Courier"/> - </dia:attribute> - <dia:attribute name="abstract_font"> - <dia:font family="monospace" style="88" name="Courier-BoldOblique"/> - </dia:attribute> - <dia:attribute name="polymorphic_font"> - <dia:font family="monospace" style="8" name="Courier-Oblique"/> - </dia:attribute> - <dia:attribute name="classname_font"> - <dia:font family="sans" style="80" name="Helvetica-Bold"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font"> - <dia:font family="sans" style="88" name="Helvetica-BoldOblique"/> - </dia:attribute> - <dia:attribute name="comment_font"> - <dia:font family="sans" style="8" name="Helvetica-Oblique"/> - </dia:attribute> - <dia:attribute name="normal_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="polymorphic_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="abstract_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="comment_font_height"> - <dia:real val="0.69999999999999996"/> - </dia:attribute> - <dia:attribute name="attributes"/> - <dia:attribute name="operations"> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#process_exists#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#kill_process#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#get_pid_list#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#...#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - </dia:attribute> - <dia:attribute name="template"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="templates"/> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="UML - Class" version="0" id="O4"> - <dia:attribute name="obj_pos"> - <dia:point val="22.835,26.9875"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="22.785,26.9375;38.4,32.9375"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="22.835,26.9875"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="15.515000000000001"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="5.9000000000000004"/> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#_psutil_[platform].c#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>#C extension#</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_attributes"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_comments"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_after_char"> - <dia:int val="40"/> - </dia:attribute> - <dia:attribute name="comment_line_length"> - <dia:int val="17"/> - </dia:attribute> - <dia:attribute name="comment_tagging"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.10000000000000001"/> - </dia:attribute> - <dia:attribute name="line_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_color"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="normal_font"> - <dia:font family="monospace" style="0" name="Courier"/> - </dia:attribute> - <dia:attribute name="abstract_font"> - <dia:font family="monospace" style="88" name="Courier-BoldOblique"/> - </dia:attribute> - <dia:attribute name="polymorphic_font"> - <dia:font family="monospace" style="8" name="Courier-Oblique"/> - </dia:attribute> - <dia:attribute name="classname_font"> - <dia:font family="sans" style="80" name="Helvetica-Bold"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font"> - <dia:font family="sans" style="88" name="Helvetica-BoldOblique"/> - </dia:attribute> - <dia:attribute name="comment_font"> - <dia:font family="sans" style="8" name="Helvetica-Oblique"/> - </dia:attribute> - <dia:attribute name="normal_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="polymorphic_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="abstract_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="comment_font_height"> - <dia:real val="0.69999999999999996"/> - </dia:attribute> - <dia:attribute name="attributes"/> - <dia:attribute name="operations"> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#process_exists#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#bool#</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"> - <dia:composite type="umlparameter"> - <dia:attribute name="name"> - <dia:string>#pid#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#int#</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="kind"> - <dia:enum val="0"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#get_process_info#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#ProcessInfo#</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"> - <dia:composite type="umlparameter"> - <dia:attribute name="name"> - <dia:string>#pid#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#int#</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="kind"> - <dia:enum val="0"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#kill_process#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#int#</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"> - <dia:composite type="umlparameter"> - <dia:attribute name="name"> - <dia:string>#pid#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#int#</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="kind"> - <dia:enum val="0"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#get_pid_list#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>#int[]#</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - </dia:attribute> - <dia:attribute name="template"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="templates"/> - </dia:object> - <dia:object type="UML - Class" version="0" id="O5"> - <dia:attribute name="obj_pos"> - <dia:point val="38.7485,8.77375"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="38.6985,8.72375;49.761,14.6238"/> - </dia:attribute> - <dia:attribute name="elem_corner"> - <dia:point val="38.7485,8.77375"/> - </dia:attribute> - <dia:attribute name="elem_width"> - <dia:real val="10.9625"/> - </dia:attribute> - <dia:attribute name="elem_height"> - <dia:real val="5.8000000000000007"/> - </dia:attribute> - <dia:attribute name="name"> - <dia:string>#System-related objects#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_attributes"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="suppress_operations"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="visible_attributes"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="visible_comments"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_operations"> - <dia:boolean val="true"/> - </dia:attribute> - <dia:attribute name="wrap_after_char"> - <dia:int val="40"/> - </dia:attribute> - <dia:attribute name="comment_line_length"> - <dia:int val="17"/> - </dia:attribute> - <dia:attribute name="comment_tagging"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="line_width"> - <dia:real val="0.0010000000000000002"/> - </dia:attribute> - <dia:attribute name="line_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="fill_color"> - <dia:color val="#ffffff"/> - </dia:attribute> - <dia:attribute name="text_color"> - <dia:color val="#000000"/> - </dia:attribute> - <dia:attribute name="normal_font"> - <dia:font family="monospace" style="0" name="Courier"/> - </dia:attribute> - <dia:attribute name="abstract_font"> - <dia:font family="monospace" style="88" name="Courier-BoldOblique"/> - </dia:attribute> - <dia:attribute name="polymorphic_font"> - <dia:font family="monospace" style="8" name="Courier-Oblique"/> - </dia:attribute> - <dia:attribute name="classname_font"> - <dia:font family="sans" style="80" name="Helvetica-Bold"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font"> - <dia:font family="sans" style="88" name="Helvetica-BoldOblique"/> - </dia:attribute> - <dia:attribute name="comment_font"> - <dia:font family="sans" style="8" name="Helvetica-Oblique"/> - </dia:attribute> - <dia:attribute name="normal_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="polymorphic_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="abstract_font_height"> - <dia:real val="0.80000000000000004"/> - </dia:attribute> - <dia:attribute name="classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="abstract_classname_font_height"> - <dia:real val="1"/> - </dia:attribute> - <dia:attribute name="comment_font_height"> - <dia:real val="0.69999999999999996"/> - </dia:attribute> - <dia:attribute name="attributes"> - <dia:composite type="umlattribute"> - <dia:attribute name="name"> - <dia:string>#TOTAL_PHYMEM#</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="value"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - </dia:composite> - </dia:attribute> - <dia:attribute name="operations"> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#get_pid_list#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#cpu_times#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#pid_exists#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - <dia:composite type="umloperation"> - <dia:attribute name="name"> - <dia:string>#...#</dia:string> - </dia:attribute> - <dia:attribute name="stereotype"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="visibility"> - <dia:enum val="0"/> - </dia:attribute> - <dia:attribute name="comment"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="abstract"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="inheritance_type"> - <dia:enum val="2"/> - </dia:attribute> - <dia:attribute name="query"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="class_scope"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="parameters"/> - </dia:composite> - </dia:attribute> - <dia:attribute name="template"> - <dia:boolean val="false"/> - </dia:attribute> - <dia:attribute name="templates"> - <dia:composite type="umlformalparameter"> - <dia:attribute name="name"> - <dia:string>##</dia:string> - </dia:attribute> - <dia:attribute name="type"> - <dia:string>##</dia:string> - </dia:attribute> - </dia:composite> - </dia:attribute> - </dia:object> - <dia:object type="Standard - Line" version="0" id="O6"> - <dia:attribute name="obj_pos"> - <dia:point val="30.6462,23.15"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="30.2393,23.0993;30.9628,27.0993"/> - </dia:attribute> - <dia:attribute name="conn_endpoints"> - <dia:point val="30.6462,23.15"/> - <dia:point val="30.5925,26.9875"/> - </dia:attribute> - <dia:attribute name="numcp"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="end_arrow"> - <dia:enum val="22"/> - </dia:attribute> - <dia:attribute name="end_arrow_length"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:attribute name="end_arrow_width"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:connections> - <dia:connection handle="0" to="O3" connection="6"/> - <dia:connection handle="1" to="O4" connection="1"/> - </dia:connections> - </dia:object> - <dia:object type="Standard - Line" version="0" id="O7"> - <dia:attribute name="obj_pos"> - <dia:point val="19.36,14.9"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="19.2919,14.8319;24.9474,18.0694"/> - </dia:attribute> - <dia:attribute name="conn_endpoints"> - <dia:point val="19.36,14.9"/> - <dia:point val="24.85,18"/> - </dia:attribute> - <dia:attribute name="numcp"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="end_arrow"> - <dia:enum val="22"/> - </dia:attribute> - <dia:attribute name="end_arrow_length"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:attribute name="end_arrow_width"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:connections> - <dia:connection handle="0" to="O2" connection="13"/> - <dia:connection handle="1" to="O3" connection="3"/> - </dia:connections> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="Standard - Line" version="0" id="O8"> - <dia:attribute name="obj_pos"> - <dia:point val="44.2298,14.5738"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="36.3402,14.5078;44.2957,18.0979"/> - </dia:attribute> - <dia:attribute name="conn_endpoints"> - <dia:point val="44.2298,14.5738"/> - <dia:point val="36.4425,18"/> - </dia:attribute> - <dia:attribute name="numcp"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="end_arrow"> - <dia:enum val="22"/> - </dia:attribute> - <dia:attribute name="end_arrow_length"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:attribute name="end_arrow_width"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:connections> - <dia:connection handle="0" to="O5" connection="6"/> - <dia:connection handle="1" to="O3" connection="4"/> - </dia:connections> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="Standard - Line" version="0" id="O9"> - <dia:attribute name="obj_pos"> - <dia:point val="27.7475,5.1"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="15.9248,5.03606;27.8114,9.43732"/> - </dia:attribute> - <dia:attribute name="conn_endpoints"> - <dia:point val="27.7475,5.1"/> - <dia:point val="16.03,9.3"/> - </dia:attribute> - <dia:attribute name="numcp"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="end_arrow"> - <dia:enum val="22"/> - </dia:attribute> - <dia:attribute name="end_arrow_length"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:attribute name="end_arrow_width"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:connections> - <dia:connection handle="0" to="O1" connection="3"/> - <dia:connection handle="1" to="O2" connection="1"/> - </dia:connections> - <dia:childnode parent="O0"/> - </dia:object> - <dia:object type="Standard - Line" version="0" id="O10"> - <dia:attribute name="obj_pos"> - <dia:point val="35.1475,5.1"/> - </dia:attribute> - <dia:attribute name="obj_bb"> - <dia:rectangle val="35.0824,5.0349;44.3334,8.88859"/> - </dia:attribute> - <dia:attribute name="conn_endpoints"> - <dia:point val="35.1475,5.1"/> - <dia:point val="44.2298,8.77375"/> - </dia:attribute> - <dia:attribute name="numcp"> - <dia:int val="1"/> - </dia:attribute> - <dia:attribute name="end_arrow"> - <dia:enum val="22"/> - </dia:attribute> - <dia:attribute name="end_arrow_length"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:attribute name="end_arrow_width"> - <dia:real val="0.5"/> - </dia:attribute> - <dia:connections> - <dia:connection handle="0" to="O1" connection="4"/> - <dia:connection handle="1" to="O5" connection="1"/> - </dia:connections> - <dia:childnode parent="O0"/> - </dia:object> - </dia:layer> -</dia:diagram> diff --git a/third_party/psutil/docs/class_diagram.png b/third_party/psutil/docs/class_diagram.png Binary files differdeleted file mode 100644 index 22a035e..0000000 --- a/third_party/psutil/docs/class_diagram.png +++ /dev/null diff --git a/third_party/psutil/docs/documentation.html b/third_party/psutil/docs/documentation.html deleted file mode 100644 index 35adcb9..0000000 --- a/third_party/psutil/docs/documentation.html +++ /dev/null @@ -1,167 +0,0 @@ - -<!-- saved from url=(0066)http://code.google.com/p/psutil/wiki/DocumentationDev?show=content --> -<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <title>DocumentationDev</title> - <script src="./documentation_files/googleapis.client__plusone.js"></script></head> - <body> - - - - - -<div> -<table> - <tbody><tr> - - - <td style="vertical-align:top; padding-left:5px"> - - <div id="wikicontent"> - <div class="vt" id="wikimaincol"> - <h1><a name="API_Reference"></a>API Reference<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#API_Reference" class="section_anchor"></a></h1><h2><a name="Exceptions"></a>Exceptions<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Exceptions" class="section_anchor"></a></h2><p>psutil.<strong>NoSuchProcess</strong><font size="3"><strong><tt>(</tt></strong></font><i>pid, name=None, msg=None</i><font size="3"><strong><tt>)</tt></strong></font> </p><blockquote>Raised when no process with the given PID is found in the current process list or when a process no longer exists (zombie). -</blockquote><p></p><p>psutil.<strong>AccessDenied</strong><font size="3"><strong><tt>(</tt></strong></font><i>pid=None, name=None, msg=None</i><font size="3"><strong><tt>)</tt></strong></font> </p><blockquote>Raised when permission to perform an action is denied. -</blockquote><p></p><p>psutil.<strong>TimeoutExpired</strong><font size="3"><strong><tt>(</tt></strong></font><i>pid=None, name=None</i><font size="3"><strong><tt>)</tt></strong></font> </p><blockquote>Raised on <tt>Process.wait(timeout)</tt> if timeout expires and process is still alive. -</blockquote><p></p><blockquote><i><strong>New in 0.2.1</strong></i> -</blockquote><hr><h2><a name="Classes"></a>Classes<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Classes" class="section_anchor"></a></h2><p>psutil.<strong>Process</strong><font size="3"><strong><tt>(</tt></strong></font><i>pid</i><font size="3"><strong><tt>)</tt></strong></font> </p><blockquote>A class which represents an OS process. -</blockquote><ul><li><strong>pid</strong><br>The process pid. </li></ul><ul><li><strong>ppid</strong><br>The process parent pid. </li></ul><ul><li><strong>parent</strong><br>Return the parent process as a <tt>Process</tt> object. If no ppid is known then return <tt>None</tt>. </li></ul><ul><li><strong>name</strong><br>The process name. </li></ul><ul><li><strong>exe</strong><br>The process executable as an absolute path name. </li></ul><ul><li><strong>cmdline</strong><br>The command line process has been called with. </li></ul><ul><li><strong>create_time</strong><br> The process creation time as a floating point number expressed in seconds since the epoch, in <a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time" rel="nofollow">UTC</a>. </li><pre class="prettyprint">>>> import os, psutil, datetime ->>> p = psutil.Process(os.getpid()) ->>> p.create_time -1307289803.47 ->>> datetime.datetime.fromtimestamp(p.create_time).strftime("%Y-%M-%d %H:%M") -'2011-03-05 18:03'</pre></ul><ul><li><strong>uids</strong><br>The <i>real</i>, <i>effective</i> and <i>saved</i> user ids of the current process as a nameduple. This is the same as <a href="http://docs.python.org/library/os.html#os.getresuid" rel="nofollow">os.getresuid()</a> but per-process. </li></ul><blockquote><i><strong>New in 0.2.1</strong></i><br><strong><i>Availability:</i></strong><i> UNIX</i> -</blockquote><ul><li><strong>gids</strong><br>The <i>real</i>, <i>effective</i> and <i>saved</i> group ids of the current process as a nameduple. This is the same as <a href="http://docs.python.org/library/os.html#os.getresgid" rel="nofollow">os.getresgid()</a> but per-process. </li></ul><blockquote><i><strong>New in 0.2.1</strong></i><br><i><strong>Availability:</strong> UNIX</i> -</blockquote><ul><li><strong>username</strong><br>The name of the user that owns the process. On UNIX this is calculated by using <i>real</i> process uid. </li></ul><blockquote><i><strong>Changed in 2.0:</strong> Windows implementation has been rewritten in C for performace and <a href="http://sourceforge.net/projects/pywin32/" rel="nofollow">pywin32</a> extension is no longer required.</i> -</blockquote><ul><li><strong>terminal</strong><br>The terminal associated with this process, if any, else None. This is similar to "tty" command but per-process. </li></ul><blockquote><i><strong>New in 0.3.0</strong></i><br><i><strong>Availability:</strong> UNIX</i> -</blockquote><ul><li><strong>status</strong><br>The current process status. The return value is one of the <tt>STATUS_*</tt> constants, which is an integer that can be used in conjunction with str() to obtain a human-readable form of the current process status. Example: </li><pre class="prettyprint">>>> import psutil, os ->>> p = psutil.Process(os.getpid()) ->>> p.status -0 ->>> p.status == psutil.STATUS_RUNNING -True ->>> str(p.status) -'running' ->>></pre></ul><blockquote><i><strong>New in 2.1</strong></i> -</blockquote><ul><li><strong>nice</strong><br>Get or set process <a href="http://blogs.techrepublic.com.com/opensource/?p=140" rel="nofollow">niceness</a> (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. </li><pre class="prettyprint">>>> p = psutil.Process(os.getpid()) ->>> p.nice -0 ->>> p.nice = 10 # set/change process priority ->>> p.nice -10</pre></ul><blockquote>On Windows this is available as well by using <a href="http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx" rel="nofollow">GetPriorityClass</a> and <a href="http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx" rel="nofollow">SetPriorityClass</a>. <tt>psutil.*_PRIORITY_CLASS</tt> constants (explained <a href="http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx" rel="nofollow">here</a>) can be used in conjunction. Example which increases process priority: -</blockquote><blockquote><pre class="prettyprint">>> p.nice = psutil.HIGH_PRIORITY_CLASS</pre> -</blockquote><blockquote><i><strong>New in 2.1</strong></i> -</blockquote><ul><li><strong>getcwd</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return a string representing the process current working directory. </li></ul><blockquote><i><strong>Availability:</strong> Windows, Linux</i> -</blockquote><ul><li><strong>get_io_counters</strong><font size="3"><strong><tt>()</tt></strong></font><br>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 <a href="http://www.mjmwired.net/kernel/Documentation/filesystems/proc.txt#1304" rel="nofollow">/proc filesysem documentation</a>. On BSD there's apparently no way to retrieve bytes counters, hence <tt>-1</tt> is returned for <tt>read_bytes</tt> and <tt>write_bytes</tt> fields. OSX is not supported. </li><pre class="prettyprint">>>> p.get_io_counters() -io(read_count=454556, write_count=3456, read_bytes=110592, write_bytes=0)</pre></ul><blockquote><i><strong>New in 2.1</strong></i><br><i><strong>Availability:</strong> Linux, Windows, FreeBSD</i> -</blockquote><ul><li><strong>get_ionice</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return <a href="http://friedcpu.wordpress.com/2007/07/17/why-arent-you-using-ionice-yet/" rel="nofollow">process I/O niceness</a> (priority) as a namedtuple including priority class and priority data. See <tt>set_ionice</tt> below for more information. </li></ul><blockquote><i><strong>New in 2.1</strong></i><br><i><strong>Availability:</strong> Linux</i> -</blockquote><ul><li><strong>set_ionice</strong><font size="3"><strong><tt>(</tt></strong></font><i>ioclass, value=None</i><font size="3"><strong><tt>)</tt></strong></font><br>Change <a href="http://friedcpu.wordpress.com/2007/07/17/why-arent-you-using-ionice-yet/" rel="nofollow">process I/O niceness</a> (priority). <i>ioclass</i> is one of the <strong><tt>IOPRIO_CLASS_*</tt></strong> constants. <i>value</i> is a number which goes from 0 to 7. The higher <i>value</i> value, the lower the I/O priority of the process. For further information refer to <a href="http://linux.die.net/man/1/ionice" rel="nofollow">ionice</a> command line utility or <a href="http://linux.die.net/man/2/ioprio_set" rel="nofollow">ioprio_set</a> system call. 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: </li><pre class="prettyprint">>>> import psutil, os ->>> p = psutil.Process(os.getpid()) ->>> p.set_ionice(psutil.IOPRIO_CLASS_IDLE) ->>></pre></ul><blockquote><i><strong>New in 2.1</strong></i><br><i><strong>Availability:</strong> Linux</i> -</blockquote><ul><li><strong>get_num_threads</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return the number of threads used by this process. </li></ul><ul><li><strong>get_threads</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return threads opened by process as a list of namedtuples including thread id and thread CPU times (user/system). </li></ul><blockquote><i><strong>New in 0.2.1</strong></i> -</blockquote><ul><li><strong>get_cpu_times</strong><font size="3"><strong><tt>()</tt></strong></font><br>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 <a href="http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1" rel="nofollow">user/system mode</a>. </li></ul><ul><li><strong>get_cpu_percent</strong><font size="3"><strong><tt>(</tt></strong></font><i>interval=0.1</i><font size="3"><strong><tt>)</tt></strong></font><br>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. In this case is recommended for accuracy that this function be called with at least 0.1 seconds between calls. </li></ul><blockquote><i><strong>Changed in 0.2.0:</strong> interval parameter was added</i> -</blockquote><ul><li><strong>get_memory_info</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return a tuple representing <a href="http://en.wikipedia.org/wiki/Resident_Set_Size" rel="nofollow">RSS</a> (Resident Set Size) and VMS (Virtual Memory Size) in bytes.<br>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. </li></ul><ul><li><strong>get_memory_percent</strong><font size="3"><strong><tt>()</tt></strong></font><br>Compare physical system memory to process resident memory and calculate process memory utilization as a percentage. </li></ul><ul><li><strong>get_children</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return the children of this process as a list of <tt>Process</tt> objects. </li></ul><ul><li><strong>get_open_files</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return files opened by process as a list of <a href="http://docs.python.org/library/collections.html?highlight=namedtuple#collections.namedtuple" rel="nofollow">namedtuples</a> including file absolute path name and file descriptor. On <strong>FreeBSD</strong> this is done by parsing <a href="http://en.wikipedia.org/wiki/Lsof" rel="nofollow">lsof</a> command output. If lsof is not installed on the system <a href="http://docs.python.org/library/exceptions.html?highlight=notimplementederror#exceptions.NotImplementedError" rel="nofollow">NotImplementedError</a> exception is raised. Example: </li><pre class="prettyprint">>>> import psutil, os ->>> f = open('file.ext', 'w') ->>> p = psutil.Process(os.getpid()) ->>> p.get_open_files() -[openfile(path='/home/giampaolo/svn/psutil/file.ext', fd=3)]</pre></ul><blockquote><i><strong>Changed in 0.2.1:</strong> OSX implementation rewritten in C; no longer requiring lsof.</i> -</blockquote><ul><li><strong>get_connections</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return all TCP and UPD connections opened by process as a list of <a href="http://docs.python.org/library/collections.html?highlight=namedtuple#collections.namedtuple" rel="nofollow">namedtuples</a>. Every namedtuple provides 6 attributes:<br><br> </li><ul><li><strong>fd</strong>: the socket file descriptor. This can be passed to <a href="http://docs.python.org/library/socket.html#socket.fromfd" rel="nofollow">socket.fromfd</a> to obtain a usable socket object. This is only available on UNIX; on Windows <tt>-1</tt> is always returned.<br> </li><li><strong>family</strong>: the address family, either <a href="http://docs.python.org/library/socket.html#socket.AF_INET" rel="nofollow">AF_INET</a> or <a href="http://docs.python.org/library/socket.html#socket.AF_INET6" rel="nofollow">AF_INET6</a> <br> </li><li><strong>type</strong>: the address type, either <a href="http://docs.python.org/library/socket.html#socket.SOCK_STREAM" rel="nofollow">SOCK_STREAM</a> or <a href="http://docs.python.org/library/socket.html#socket.SOCK_DGRAM" rel="nofollow">SOCK_DGRAM</a> <br> </li><li><strong>local_address</strong>: the local address as a <tt>(ip, port)</tt> tuple. <br> </li><li><strong>remote_address</strong>: the remote address as a <tt>(ip, port)</tt> tuple. When the remote endpoint is not connected the tuple is empty. <br> </li><li><strong>status</strong>: a string representing the TCP connections status. String values are supposed to match Linux's <a href="http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h" rel="nofollow">tcp_states.h</a> header file across all platforms. For UDP sockets this is always going to be an empty string.<br> </li></ul></ul><blockquote>Example: -<pre class="prettyprint">>>> p = psutil.Process(1694) ->>> p.name -'firefox' ->>> 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')]</pre>On <strong>FreeBSD</strong> this is implemented by parsing <a href="http://en.wikipedia.org/wiki/Lsof" rel="nofollow">lsof</a> command output. If lsof is not installed on the system <a href="http://docs.python.org/library/exceptions.html?highlight=notimplementederror#exceptions.NotImplementedError" rel="nofollow">NotImplementedError</a> exception is raised and for third party processes (different than <tt>os.getpid()</tt>) results can differ depending on user privileges.<br> -</blockquote><blockquote><i><strong>Changed in 0.2.1:</strong> OSX implementation rewritten in C; no longer requiring lsof.</i> -</blockquote><ul><li><strong>is_running</strong><font size="3"><strong><tt>()</tt></strong></font><br>Return whether the current process is running in the current process list. </li></ul><ul><li><strong>send_signal</strong><font size="3"><strong><tt>(</tt></strong></font><i>signal</i><font size="3"><strong><tt>)</tt></strong></font><br>Send a signal to process (see <a href="http://docs.python.org/library/signal.html" rel="nofollow">signal module</a> constants). On Windows only <tt>SIGTERM</tt> is valid and is treated as an alias for <tt>kill()</tt>. </li></ul><ul><li><strong>suspend</strong><font size="3"><strong><tt>()</tt></strong></font><br>Suspend process execution with <tt>SIGSTOP</tt> signal. On Windows this is done by suspending all process threads execution. </li></ul><ul><li><strong>resume</strong><font size="3"><strong><tt>()</tt></strong></font><br>Resume process execution with <tt>SIGCONT</tt> signal. On Windows this is done by resuming all process threads execution. </li></ul><ul><li><strong>terminate</strong><font size="3"><strong><tt>()</tt></strong></font><br>Terminate the process with <tt>SIGTERM</tt> signal. On Windows this is an alias for <tt>kill()</tt>. </li></ul><ul><li><strong>kill</strong><font size="3"><strong><tt>()</tt></strong></font><br>Kill the current process by using <tt>SIGKILL</tt> signal. </li></ul><blockquote><i><strong>Changed in 0.2.0:</strong> no longer accepts <tt>sig</tt> keyword argument - use <tt>send_signal()</tt> instead. </i> -</blockquote><ul><li><strong>wait</strong><font size="3"><strong><tt>(</tt></strong></font><i>timeout=None</i><font size="3"><strong><tt>)</tt></strong></font><br>Wait for process termination and if the process is a children of the current one also return the exit code, else <tt>None</tt>. On Windows there's no such limitation (exit code is always returned). If the process is already terminated does not raise <tt>NoSuchProcess</tt> exception but just return <tt>None</tt> immediately. If <i>timeout</i> is specified and process is still alive raises <tt>TimeoutExpired</tt> exception. </li></ul><blockquote><i><strong>New in 0.2.1</strong></i> -</blockquote><p><br><br> psutil.<strong>Popen</strong><font size="3"><strong><tt>(</tt></strong></font><tt>*args, **kwargs</tt><font size="3"><strong><tt>)</tt></strong></font> </p><blockquote>A more convenient interface to stdlib <a href="http://docs.python.org/library/subprocess.html#subprocess.Popen" rel="nofollow">subprocess.Popen</a>. It starts a sub process and deals with it exactly as when using subprocess.Popen class but in addition also provides all the properties and methods of psutil.Process class in a unique interface. For method names common to both classes such as <i>kill()</i> and <i>terminate()</i>, psutil.Process implementation takes precedence. For a complete documentation refers to <a href="http://docs.python.org/library/subprocess.html" rel="nofollow">subprocess module documentation</a>. -<pre class="prettyprint">>>> import psutil ->>> from subprocess import PIPE ->>> p = psutil.Popen(["/usr/bin/python", "-c", "print 'hi'"], stdout=PIPE) ->>> p.name -'python' ->>> p.uids -user(real=1000, effective=1000, saved=1000) ->>> p.username -'giampaolo' ->>> p.communicate() -('hi\n', None) ->>> p.wait(timeout=2) -0 ->>></pre></blockquote><blockquote><i><strong>New in 0.2.1</strong></i> -</blockquote><hr><h2><a name="Functions"></a>Functions<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Functions" class="section_anchor"></a></h2><p>psutil.<strong>get_pid_list</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>Return a list of current running PIDs. -</blockquote><p></p><p>psutil.<strong>pid_exists</strong><font size="3"><strong><tt>(</tt></strong></font><i>pid</i><font size="3"><strong><tt>)</tt></strong></font><br> </p><blockquote>Check whether the given PID exists in the current process list. This is faster than doing <tt>pid in psutil.get_pid_list()</tt> and should be preferred. -</blockquote><p></p><p>psutil.<strong>process_iter</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>Return an iterator yielding a Process class instances for all running processes on the local machine. This should be preferred over doing <tt>for pid in psutil.get_pid_list(): psutil.Process(pid)</tt> as it safe from race conditions. -</blockquote><p></p><hr><h2><a name="System_related_functions"></a>System related functions<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#System_related_functions" class="section_anchor"></a></h2><h3><a name="CPU"></a>CPU<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#CPU" class="section_anchor"></a></h3><p>psutil.<strong>cpu_percent</strong><font size="3"><strong><tt>(</tt></strong></font><i>interval=0.1, percpu=False</i><font size="3"><strong><tt>)</tt></strong></font><br> </p><blockquote>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. In this case is recommended for accuracy that this function be called with at least 0.1 seconds between calls.<br>When <i>percpu</i> 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. -</blockquote><p></p><pre class="prettyprint">>>> # blocking, system-wide ->>> psutil.cpu_percent(interval=1) -2.0 ->>> ->>> # blocking, per-cpu ->>> psutil.cpu_percent(interval=1, percpu=True) -[2.0, 1.0] ->>> ->>> # non-blocking (percentage since last call) ->>> psutil.cpu_percent(interval=0) -2.9 ->>></pre><blockquote><i><strong>Changed in 0.2.0:</strong> interval parameter was added</i><br><i><strong>Changed in 0.3.0:</strong> percpu parameter was added</i> -</blockquote><p>psutil.<strong>cpu_times</strong><font size="3"><strong><tt>(</tt></strong></font><i>percpu=False</i><font size="3"><strong><tt>)</tt></strong></font><br> </p><blockquote>Return system CPU times as a namedtuple. Every attribute represents the time CPU has spent in the given mode.<br>The attributes availability varies depending on the platform. Here follows a list of all available attributes: -</blockquote><blockquote>- user<br> -- system<br> -- idle<br> -- nice <i>(UNIX)</i><br> -- iowait <i>(Linux)</i><br> -- irq <i>(Linux, FreeBSD)</i><br> -- softirq <i>(Linux)</i> -</blockquote><p></p><blockquote>When <i>percpu</i> is True return a list of nameduples 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. -</blockquote><blockquote><i><strong>Changed in 0.3.0:</strong> percpu parameter was added</i> -</blockquote><hr><h3><a name="Memory"></a>Memory<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Memory" class="section_anchor"></a></h3><p>psutil.<strong>phymem_usage</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>Return the amount of total, used and free physical memory on the system in bytes plus the percentage usage. -<p></p><pre class="prettyprint">>>> psutil.phymem_usage() -usage(total=4153868288, used=2854199296, free=1299668992, percent=34.6)</pre><i><strong>New in 0.3.0</strong></i> -</blockquote><p>psutil.<strong>virtmem_usage</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>Return the amount of total, used and free virtual memory on the system in bytes plus the percentage usage.<br>On Linux they match the values returned by <tt>free</tt> command line utility. On OS X and FreeBSD they represent the same values as returned by <tt>sysctl vm.vmtotal</tt>. On Windows they are determined by reading the <tt>*PageFile</tt> values of <a href="http://msdn.microsoft.com/en-us/library/aa366770(VS.85).aspx" rel="nofollow">MEMORYSTATUSEX</a> structure. -<p></p><pre class="prettyprint">>>> psutil.virtmem_usage() -usage(total=2097147904, used=4096, free=2097143808, percent=0.0)</pre><i><strong>New in 0.3.0</strong></i> -</blockquote><p>psutil.<strong>cached_phymem</strong><font size="3"><strong><tt>()</tt></strong></font><br> psutil.<strong>phymem_buffers</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>Return the amount of cached memory and physical memory buffers on the system, in bytes. Thet reflects the "cached" and "buffers" columns of free command line utility on Linux. -</blockquote><p></p><blockquote><i><strong>Availability:</strong> Linux</i> -</blockquote><p>psutil.<strong>avail_phymem</strong><font size="3"><strong><tt>()</tt></strong></font><br> psutil.<strong>used_phymem</strong><font size="3"><strong><tt>()</tt></strong></font><br> psutil.<strong>total_virtmem</strong><font size="3"><strong><tt>()</tt></strong></font><br> psutil.<strong>avail_virtmem</strong><font size="3"><strong><tt>()</tt></strong></font><br> psutil.<strong>used_virtmem</strong><font size="3"><strong><tt>()</tt></strong></font><br> </p><blockquote>These functions are deprecated by <i>psutil.phymem_usage()</i> and <i>psutil.virtmem_usage()</i>. Use them instead. -</blockquote><p></p><blockquote><i><strong>Deprecated in 0.3.0</strong></i> -</blockquote><hr><h3><a name="Disk"></a>Disk<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Disk" class="section_anchor"></a></h3><p>psutil.<strong>disk_partitions</strong><font size="3"><strong><tt>(</tt></strong></font><i>all=False</i><font size="3"><strong><tt>)</tt></strong></font><br> </p><blockquote>Return all mounted disk partitions as a list of namedtuples including device, mount point and filesystem type, similarly to "df" command on posix. <br>If <i>all</i> 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 <a href="http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html" rel="nofollow">/dev/shm</a>).<br> Namedtuple's 'fstype' field is a string which varies depending on the platform. <br>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). <br>On Windows it is determined via <a href="http://msdn.microsoft.com/en-us/library/aa364939(v=vs.85).aspx" rel="nofollow">GetDriveType</a> and can be either "removable", "fixed", "remote", "cdrom", "unmounted" or "ramdisk". <br>On OSX and FreeBSD it is retrieved via <a href="http://www.manpagez.com/man/2/getfsstat/" rel="nofollow">getfsstat(2)</a>. <br>See <a href="http://psutil.googlecode.com/svn/trunk/examples/disk_usage.py" rel="nofollow">examples/disk_usage.py</a> script providing an example usage. -<p></p><pre class="prettyprint">>>> psutil.get_partitions() -[partition(device='/dev/sda3', mountpoint='/', fstype='ext4'), - partition(device='/dev/sda7', mountpoint='/home', fstype='ext4')] ->>></pre></blockquote><blockquote><i><strong>New in 0.3.0</strong></i> -</blockquote><p>psutil.<strong>disk_usage</strong><font size="3"><strong><tt>(</tt></strong></font><i>path</i><font size="3"><strong><tt>)</tt></strong></font><br> </p><blockquote>Return disk usage statistics about the given <i>path</i> as a namedtuple including total, used and free space expressed in bytes plus the percentage usage. OSError is raised if path does not exist. See <a href="http://psutil.googlecode.com/svn/trunk/examples/disk_usage.py" rel="nofollow">examples/disk_usage.py</a> script providing an example usage. -<p></p><pre class="prettyprint">>>> psutil.disk_usage('/') -usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)</pre></blockquote><blockquote><i><strong>New in 0.3.0</strong></i> -</blockquote><hr><h2><a name="Constants"></a>Constants<a href="http://code.google.com/p/psutil/wiki/DocumentationDev?show=content#Constants" class="section_anchor"></a></h2><p>psutil.<strong>TOTAL_PHYMEM</strong><br> </p><blockquote>The amount of total physical memory on the system, in bytes. -</blockquote><p></p><p>psutil.<strong>NUM_CPUS</strong><br> </p><blockquote>The number of CPUs on the system. This is preferable than using <tt>os.environ['NUMBER_OF_PROCESSORS']</tt> as it is more accurate and always available. -</blockquote><p></p><p>psutil.<strong>BOOT_TIME</strong><br> </p><blockquote>A number indicating the system boot time expressed in seconds since the epoch. -</blockquote><p></p><blockquote><i><strong>New in 0.2.1</strong></i> -</blockquote><p>psutil.<strong>ABOVE_NORMAL_PRIORITY_CLASS</strong><br> psutil.<strong>BELOW_NORMAL_PRIORITY_CLASS</strong><br> psutil.<strong>HIGH_PRIORITY_CLASS</strong><br> psutil.<strong>IDLE_PRIORITY_CLASS</strong><br> psutil.<strong>NORMAL_PRIORITY_CLASS</strong><br> psutil.<strong>REALTIME_PRIORITY_CLASS</strong><br> </p><blockquote>A set of integers representing the priority of a process on Windows (see <a href="http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx" rel="nofollow">MSDN documentation</a>). They can be used in conjunction with <tt>psutil.Process.nice</tt> to get or set process priority. -</blockquote><p></p><blockquote><i><strong>New in 0.2.1</strong></i><br><i><strong>Availability:</strong> Windows</i> -</blockquote><p>psutil.<strong>IOPRIO_CLASS_NONE</strong><br> psutil.<strong>IOPRIO_CLASS_RT</strong><br> psutil.<strong>IOPRIO_CLASS_BE</strong><br> psutil.<strong>IOPRIO_CLASS_IDLE</strong><br> </p><blockquote>A set of integers representing the I/O priority of a process on Linux. They can be used in conjunction with <tt>psutil.Process.get_ionice()</tt> and <tt>psutil.Process.set_ionice()</tt> to get or set process I/O priority. For further information refer to <a href="http://linux.die.net/man/1/ionice" rel="nofollow">ionice</a> command line utility or <a href="http://linux.die.net/man/2/ioprio_get" rel="nofollow">ioprio_get</a> system call. -</blockquote><p></p><blockquote><i><strong>New in 0.2.1</strong></i><br><i><strong>Availability:</strong> Linux</i> -</blockquote><p>psutil.<strong>STATUS_RUNNING</strong><br> psutil.<strong>STATUS_SLEEPING</strong><br> psutil.<strong>STATUS_DISK_SLEEP</strong><br> psutil.<strong>STATUS_STOPPED</strong><br> psutil.<strong>STATUS_TRACING_STOP</strong><br> psutil.<strong>STATUS_ZOMBIE</strong><br> psutil.<strong>STATUS_DEAD</strong><br> psutil.<strong>STATUS_WAKE_KILL</strong><br> psutil.<strong>STATUS_WAKING</strong><br> psutil.<strong>STATUS_IDLE</strong><br> psutil.<strong>STATUS_LOCKED</strong><br> psutil.<strong>STATUS_WAITING</strong><br> </p><blockquote>A set of integers representing the status of a process. To be used in conjunction with <tt>psutil.Process.status</tt> property. If used with str() return a human-readable status string. -</blockquote><p></p><blockquote><i><strong>New in 0.2.1</strong></i><br><i><strong> -</strong></i></blockquote> - </div> - </div> - </td></tr><tr> -</tr></tbody></table> - </div> - - - - -<script type="text/javascript" src="./documentation_files/dit_scripts.js"></script> - - -<script type="text/javascript" src="./documentation_files/plusone.js"> -</script> - - - - -</body></html>
\ No newline at end of file diff --git a/third_party/psutil/docs/index.html b/third_party/psutil/docs/index.html deleted file mode 100644 index 4ac43f4..0000000 --- a/third_party/psutil/docs/index.html +++ /dev/null @@ -1,125 +0,0 @@ -<html> - <head> - <title>Home</title> - </head> - <body> - - - - - -<div> -<table> - <tr> - - - <td style="vertical-align:top; padding-left:5px"> - - <div id="wikicontent"> - <div class="vt" id="wikimaincol"> - <h1><a name="Summary"></a>Summary<a href="#Summary" class="section_anchor"></a></h1><p>psutil is a module providing an interface for retrieving information on all running processes and system utilization (CPU, disk, memory) in a portable way by using <strong>Python</strong>, implementing many functionalities offered by command line tools such as: </p><ul><li>ps </li><li>top </li><li>df </li><li>kill </li><li>free </li><li>lsof </li><li>netstat </li><li>nice </li><li>ionice </li><li>uptime </li><li>tty </li></ul><p>It currently supports <strong>Linux</strong>, <strong>Windows</strong>, <strong>OSX</strong> and <strong>FreeBSD</strong> both <strong>32-bit</strong> and <strong>64-bit</strong> with Python versions from <strong>2.4</strong> to <strong>3.3</strong> by using a single code base. </p><p><a href="http://code.google.com/p/psutil/#Donate" rel="nofollow"></a> </p><h1><a name="Example_usages"></a>Example usages<a href="#Example_usages" class="section_anchor"></a></h1><h3><a name="CPU"></a>CPU<a href="#CPU" class="section_anchor"></a></h3><pre class="prettyprint">>>> 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, 34.2] -[7.0, 8.5] -[1.2, 9.0] ->>></pre><h3><a name="Memory"></a>Memory<a href="#Memory" class="section_anchor"></a></h3><pre class="prettyprint">>>> psutil.phymem_usage() -usage(total=4153868288, used=2854199296, free=1299668992, percent=34.6) ->>> psutil.virtmem_usage() -usage(total=2097147904, used=4096, free=2097143808, percent=0.0) ->>></pre><h3><a name="Disks"></a>Disks<a href="#Disks" class="section_anchor"></a></h3><pre class="prettyprint">>>> psutil.get_partitions() -[partition(device='/dev/sda3', mountpoint='/', fstype='ext4'), - partition(device='/dev/sda7', mountpoint='/home', fstype='ext4')] ->>> ->>> psutil.disk_usage('/') -usage(total=21378641920, used=4809781248, free=15482871808, percent=22.5) ->>></pre><h3><a name="Process_management"></a>Process management<a href="#Process_management" class="section_anchor"></a></h3><pre class="prettyprint">>>> 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.cmdline -['/usr/bin/python', 'main.py'] ->>> str(p.status) -'running' ->>> ->>> p.uids -user(real=1000, effective=1000, saved=1000) ->>> p.gids -group(real=1000, effective=1000, saved=1000) ->>> p.username -'giampaolo' ->>> p.create_time -1267551141.5019531 ->>> p.get_cpu_percent(interval=1.0) -12.1 ->>> p.get_memory_percent() -0.63423 ->>> p.get_memory_info() -meminfo(rss=7471104, vms=68513792) ->>> 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_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.nice -0 ->>> p.nice = 10 # set/change process priority ->>> p.nice -10 ->>> ->>> p.suspend() ->>> p.resume() ->>> ->>> p.terminate() ->>> p.wait(timeout=3) -0 ->>> ->>> psutil.test() -UID PID %CPU %MEM VSZ RSS START TIME COMMAND -0 0 0.0 0.0 0 0 00:12 00:00 [sched] -0 1 0.0 0.3 1740 600 00:12 00:04 /sbin/init -0 2 0.0 0.0 0 0 00:12 00:00 [kthreadd] -0 3 0.1 0.0 0 0 00:12 00:00 [migration/0] -... -0 13239 0.0 2.6 13604 1044 00:38 00:00 /usr/sbin/smbd -D -1000 23648 1.1 2.4 12512 2008 14:43 00:06 sshd: user@pts/2 -1000 23649 0.0 1.2 5944 3340 14:43 00:00 -bash -0 25926 0.3 1.1 5432 3072 17:55 00:00 -su -0 28655 0.0 1.0 4932 3204 21:58 00:00 python _psutil.py ->>></pre><h1><a name="Donate"></a>Donate<a href="#Donate" class="section_anchor"></a></h1><p>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 it's future development please consider donating us (Giampaolo Rodolà and Jay Loden) some money. We only ask for a small donation, but of course we appreciate any amount. </p><p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8" rel="nofollow"></a> </p><h2><a name="People_who_donated_so_far"></a>People who donated so far<a href="#People_who_donated_so_far" class="section_anchor"></a></h2><ul><li>Kim Gräsman </li></ul><h1><a name="Mailing_lists"></a>Mailing lists<a href="#Mailing_lists" class="section_anchor"></a></h1><p><strong>Users</strong><br><a href="http://groups.google.com/group/psutil/" rel="nofollow">http://groups.google.com/group/psutil/</a> </p><p><strong>Developers</strong><br><a href="http://groups.google.com/group/psutil-dev/" rel="nofollow">http://groups.google.com/group/psutil-dev/</a> </p><p><strong>SVN commits and issue tracker changes</strong><br><a href="http://groups.google.com/group/psutil-commits/" rel="nofollow">http://groups.google.com/group/psutil-commits/</a> </p><h1><a name="Contribute"></a>Contribute<a href="#Contribute" class="section_anchor"></a></h1><p>If you want to help or just give us suggestions about the project and other related things, subscribe to the <a href="http://groups.google.com/group/psutil" rel="nofollow">discussion mailing list</a>. If you want to talk with project team members about psutil and other related things feel free to contact us at the following addresses: </p><p><table class="wikitable"><tr><td style="border: 1px solid #ccc; padding: 5px;"> <strong>Name</strong> </td><td style="border: 1px solid #ccc; padding: 5px;"> <strong>Country</strong> </td><td style="border: 1px solid #ccc; padding: 5px;"> <strong>E-mail</strong> </td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> Giampaolo Rodola' </td><td style="border: 1px solid #ccc; padding: 5px;"> Turin (Italy) </td><td style="border: 1px solid #ccc; padding: 5px;"> g.rodola at gmail dot com </td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> Jay Loden </td><td style="border: 1px solid #ccc; padding: 5px;"> New Jersey (USA) </td><td style="border: 1px solid #ccc; padding: 5px;"> jloden at gmail dot com </td></tr> </table></p><p>Feedbacks and suggestions are greatly appreciated as well as new testers and coders willing to join the development.<br> For any bug report, patch proposal or feature request, add an entry into the <a href="http://code.google.com/p/psutil/issues/list" rel="nofollow">Issue Tracker</a>.<br> </p><p>Thank you. </p> - </body> -</html> diff --git a/third_party/psutil/docs/milestones.lnk.html b/third_party/psutil/docs/milestones.lnk.html deleted file mode 100644 index 83904c8..0000000 --- a/third_party/psutil/docs/milestones.lnk.html +++ /dev/null @@ -1,12 +0,0 @@ -<html> -<head> - <meta http-equiv="refresh" content="2; http://code.google.com/p/psutil/wiki/Milestones"> - <title>Redirecting to Milestones...</title> -</head> - -<body> -<p>Redirecting to: <a href="http://code.google.com/p/psutil/wiki/Milestones">http://code.google.com/p/psutil/wiki/Milestones</a><br></p> -<p>You'll be redirected in 2 seconds...</p> - -</body> -</html> diff --git a/third_party/psutil/examples/disk_usage.py b/third_party/psutil/examples/disk_usage.py deleted file mode 100644 index 23f2d0c..0000000 --- a/third_party/psutil/examples/disk_usage.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -# $Id: disk_usage.py 1143 2011-10-05 19:11:59Z 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. - -""" -List all mounted disk partitions a-la "df -h" command. -""" - -import sys -import psutil - -def convert_bytes(n): - if n == 0: - return "0B" - 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) - - -def main(): - templ = "%-17s %8s %8s %8s %5s%% %9s %s" - print templ % ("Device", "Total", "Used", "Free", "Use ", "Type", "Mount") - for part in psutil.disk_partitions(all=False): - usage = psutil.disk_usage(part.mountpoint) - print templ % (part.device, - convert_bytes(usage.total), - convert_bytes(usage.used), - convert_bytes(usage.free), - int(usage.percent), - part.fstype, - part.mountpoint) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/third_party/psutil/examples/iotop.py b/third_party/psutil/examples/iotop.py deleted file mode 100644 index 2307c75..0000000 --- a/third_party/psutil/examples/iotop.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -# -# $Id: iotop.py 1143 2011-10-05 19:11:59Z 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. - -""" -A clone of iotop (http://guichaz.free.fr/iotop/) showing real time -disk I/O statistics. - -It works on UNIX only as curses module is not available on Windows. - -Author: Giampaolo Rodola' <g.rodola@gmail.com> -""" - -import time -import curses -import atexit - -import psutil - -win = curses.initscr() - -def bytes2human(n): - """ - >>> bytes2human(10000) - '9.8 K/s' - >>> bytes2human(100001221) - '95.4 M/s' - """ - 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 '%.2f %s/s' % (value, s) - return "0.00 B/s" - -def poll(interval): - """Calculate IO usage by comparing IO statics before and - after the interval. - Return a tuple including all currently running processes - sorted by IO activity and total disks I/O activity. - """ - # first get a list of all processes and disk io counters - procs = [p for p in psutil.process_iter()] - for p in procs[:]: - try: - p._before = p.get_io_counters() - except psutil.Error: - procs.remove(p) - continue - disks_before = psutil.disk_io_counters() - - # sleep some time - time.sleep(interval) - - # then retrieve the same info again - for p in procs[:]: - try: - p._after = p.get_io_counters() - p._cmdline = ' '.join(p.cmdline) - if not p._cmdline: - p._cmdline = p.name - p._username = p.username - except psutil.NoSuchProcess: - procs.remove(p) - disks_after = psutil.disk_io_counters() - - # finally calculate results by comparing data before and - # after the interval - for p in procs: - p._read_per_sec = p._after.read_bytes - p._before.read_bytes - p._write_per_sec = p._after.write_bytes - p._before.write_bytes - p._total = p._read_per_sec + p._write_per_sec - - disks_read_per_sec = disks_after.read_bytes - disks_before.read_bytes - disks_write_per_sec = disks_after.write_bytes - disks_before.write_bytes - - # sort processes by total disk IO so that the more intensive - # ones get listed first - processes = sorted(procs, key=lambda p: p._total, reverse=True) - - return (processes, disks_read_per_sec, disks_write_per_sec) - -def run(win): - """Print results on screen by using curses.""" - curses.endwin() - templ = "%-5s %-7s %11s %11s %s" - interval = 0 - while 1: - procs, disks_read, disks_write = poll(interval) - win.erase() - - disks_tot = "Total DISK READ: %s | Total DISK WRITE: %s" \ - % (bytes2human(disks_read), bytes2human(disks_write)) - win.addstr(0, 0, disks_tot) - - header = templ % ("PID", "USER", "DISK READ", "DISK WRITE", "COMMAND") - header += " " * (win.getmaxyx()[1] - len(header)) - win.addstr(1, 0, header, curses.A_REVERSE) - - lineno = 2 - for p in procs: - line = templ % (p.pid, - p._username[:7], - bytes2human(p._read_per_sec), - bytes2human(p._write_per_sec), - p._cmdline) - try: - win.addstr(lineno, 0, line) - except curses.error: - break - win.refresh() - lineno += 1 - interval = 1 - -def main(): - def tear_down(): - win.keypad(0) - curses.nocbreak() - curses.echo() - curses.endwin() - - atexit.register(tear_down) - try: - run(win) - except (KeyboardInterrupt, SystemExit): - pass - -if __name__ == '__main__': - main() diff --git a/third_party/psutil/examples/killall.py b/third_party/psutil/examples/killall.py deleted file mode 100644 index 5381b54..0000000 --- a/third_party/psutil/examples/killall.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# -# $Id: killall.py 1143 2011-10-05 19:11:59Z 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. - -""" -Kill a process by name. -""" - -import os -import sys -import psutil - -def main(): - if len(sys.argv) != 2: - sys.exit('usage: %s name' % __file__) - else: - NAME = sys.argv[1] - - killed = [] - for proc in psutil.process_iter(): - if proc.name == NAME and proc.pid != os.getpid(): - proc.kill() - killed.append(proc.pid) - if not killed: - sys.exit('%s: no process found' % NAME) - else: - sys.exit(0) - -sys.exit(main()) diff --git a/third_party/psutil/examples/process_detail.py b/third_party/psutil/examples/process_detail.py deleted file mode 100644 index 4c791d1..0000000 --- a/third_party/psutil/examples/process_detail.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python -# -# $Id: process_detail.py 1143 2011-10-05 19:11:59Z 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. - -""" -Print detailed information about a process. -""" - -import os -import datetime -import socket -import sys - -import psutil -from psutil._compat import namedtuple - - -def convert_bytes(n): - if n == 0: - return '0B' - 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) - -def print_(a, b): - if sys.stdout.isatty(): - fmt = '\x1b[1;32m%-17s\x1b[0m %s' %(a, b) - else: - fmt = '%-15s %s' %(a, b) - print fmt - -def run(pid): - p = psutil.Process(pid) - if p.parent: - parent = '(%s)' % p.parent.name - else: - parent = '' - started = datetime.datetime.fromtimestamp(p.create_time).strftime('%Y-%M-%d %H:%M') - io = p.get_io_counters() - mem = p.get_memory_info() - mem = '%s%% (resident=%s, virtual=%s) ' %(round(p.get_memory_percent(), 1), - convert_bytes(mem.rss), - convert_bytes(mem.vms)) - cpu_times = p.get_cpu_times() - cpu_percent = p.get_cpu_percent(0) - children = p.get_children() - files = p.get_open_files() - threads = p.get_threads() - connections = p.get_connections() - - print_('pid', p.pid) - print_('name', p.name) - print_('exe', p.exe) - print_('parent', '%s %s' % (p.ppid, parent)) - print_('cmdline', ' '.join(p.cmdline)) - print_('started', started) - print_('user', p.username) - if os.name == 'posix': - print_('uids', 'real=%s, effective=%s, saved=%s' % p.uids) - print_('gids', 'real=%s, effective=%s, saved=%s' % p.gids) - print_('terminal', p.terminal or '') - if hasattr(p, 'getcwd'): - print_('cwd', p.getcwd()) - print_('memory', mem) - print_('cpu', '%s%% (user=%s, system=%s)' % (cpu_percent, - cpu_times.user, - cpu_times.system)) - print_('status', p.status) - print_('niceness', p.nice) - print_('num threads', p.get_num_threads()) - if hasattr(p, 'get_io_counters'): - 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)) - - if files: - print_('open files', '') - for file in files: - print_('', 'fd=%s %s ' % (file.fd, file.path)) - - if threads: - print_('running threads', '') - for thread in threads: - print_('', 'id=%s, user-time=%s, sys-time=%s' \ - % (thread.id, thread.user_time, thread.system_time)) - if connections: - print_('open connections', '') - for conn in connections: - type = 'TCP' if conn.type == socket.SOCK_STREAM else 'UDP' - lip, lport = conn.local_address - if not conn.remote_address: - rip, rport = '*', '*' - else: - rip, rport = conn.remote_address - print_('', '%s:%s -> %s:%s type=%s status=%s' \ - % (lip, lport, rip, rport, type, conn.status)) - -def main(argv=None): - if argv is None: - argv = sys.argv - if len(argv) == 1: - sys.exit(run(os.getpid())) - elif len(argv) == 2: - sys.exit(run(int(argv[1]))) - else: - sys.exit('usage: %s [pid]' % __file__) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/third_party/psutil/psutil/__init__.py b/third_party/psutil/psutil/__init__.py deleted file mode 100644 index 93724fc..0000000 --- a/third_party/psutil/psutil/__init__.py +++ /dev/null @@ -1,822 +0,0 @@ -#!/usr/bin/env python -# -# $Id: __init__.py 1142 2011-10-05 18:45:49Z 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. - -"""psutil is a module providing convenience functions for managing -processes and gather system information in a portable way by using -Python. -""" - -__version__ = "0.3.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 - "test", "pid_exists", "get_pid_list", "process_iter", "get_process_list", - "phymem_usage", "virtmem_usage" - "cpu_times", "per_cpu_times", "cpu_percent", "per_cpu_percent", - "network_io_counters", "disk_io_counters", - ] - -import sys -import os -import time -import signal -import warnings -import errno -import subprocess -try: - import pwd -except ImportError: - pwd = None - -from psutil.error import Error, NoSuchProcess, AccessDenied, TimeoutExpired -from psutil._compat import property -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 - ) - -# import the appropriate module for our platform only -if sys.platform.lower().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 - -elif sys.platform.lower().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) - -elif sys.platform.lower().startswith("darwin"): - import psutil._psosx as _psplatform - -elif sys.platform.lower().startswith("freebsd"): - import psutil._psbsd as _psplatform - -else: - raise NotImplementedError('platform %s is not supported' % sys.platform) - -__all__.extend(_psplatform.__extra__all__) - -NUM_CPUS = _psplatform.NUM_CPUS -BOOT_TIME = _psplatform.BOOT_TIME -TOTAL_PHYMEM = _psplatform.phymem_usage()[0] - -get_pid_list = _psplatform.get_pid_list -pid_exists = _psplatform.pid_exists - - -class Process(object): - """Represents an OS process.""" - - def __init__(self, pid): - """Create a new Process object, raises NoSuchProcess if the PID - does not exist, and ValueError if the parameter is not an - integer PID. - """ - if not isinstance(pid, int): - raise ValueError("an integer is required") - if not pid_exists(pid): - raise NoSuchProcess(pid, None, "no process found with pid %s" % pid) - self._pid = pid - # platform-specific modules define an _psplatform.Process - # implementation class - self._platform_impl = _psplatform.Process(pid) - self._last_sys_cpu_times = None - self._last_proc_cpu_times = None - - def __str__(self): - try: - pid = self.pid - name = repr(self.name) - except NoSuchProcess: - details = "(pid=%s (terminated))" % self.pid - except AccessDenied: - details = "(pid=%s)" % (self.pid) - else: - details = "(pid=%s, name=%s)" % (pid, name) - return "%s.%s%s" % (self.__class__.__module__, - self.__class__.__name__, details) - - def __repr__(self): - return "<%s at %s>" % (self.__str__(), id(self)) - - @property - def pid(self): - """The process pid.""" - return self._pid - - @property - def ppid(self): - """The process parent pid.""" - return self._platform_impl.get_process_ppid() - - @property - def parent(self): - """Return the parent process as a Process object. If no parent - pid is known return None. - """ - ppid = self.ppid - if ppid is not None: - try: - return Process(ppid) - except NoSuchProcess: - pass - - @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". - cmdline = self.cmdline - 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 - - @property - def exe(self): - """The process executable as an absolute path name.""" - exe = self._platform_impl.get_process_exe() - # if we have the cmdline but not the exe, figure it out from argv[0] - if not exe: - cmdline = self.cmdline - if cmdline and hasattr(os, 'access') and hasattr(os, 'X_OK'): - _exe = os.path.realpath(cmdline[0]) - if os.path.isfile(_exe) and os.access(_exe, os.X_OK): - return _exe - if not exe: - raise AccessDenied(self.pid, self._platform_impl._process_name) - return exe - - @property - def cmdline(self): - """The command line process has been called with.""" - return self._platform_impl.get_process_cmdline() - - @property - def status(self): - """The process current status as a STATUS_* constant.""" - return self._platform_impl.get_process_status() - - @property - def nice(self): - """Get or set process niceness (priority).""" - return self._platform_impl.get_process_nice() - - @nice.setter - def nice(self, value): - # invoked on "p.nice = num"; change process niceness - return self._platform_impl.set_process_nice(value) - - 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() - - @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 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 - else: - return self._platform_impl.get_process_username() - - @property - def create_time(self): - """The process creation time as a floating point number - expressed in seconds since the epoch, in UTC. - """ - return self._platform_impl.get_process_create_time() - - # available for Windows and Linux only - if hasattr(_psplatform.Process, "get_process_cwd"): - - def getcwd(self): - """Return a string representing the process current working - directory. - """ - return self._platform_impl.get_process_cwd() - - # Linux, BSD and Windows only - if hasattr(_psplatform.Process, "get_process_io_counters"): - - 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. - """ - return self._platform_impl.get_process_io_counters() - - # available only on Linux - if hasattr(_psplatform.Process, "get_process_ionice"): - - def get_ionice(self): - """Return process I/O niceness (priority) as a namedtuple.""" - return self._platform_impl.get_process_ionice() - - def set_ionice(self, ioclass, value=None): - """Set process I/O niceness (priority). - ioclass is one of the IOPRIO_CLASS_* constants. - iodata is a number which goes from 0 to 7. The higher the - value, the lower the I/O priority of the process. - """ - return self._platform_impl.set_process_ionice(ioclass, value) - - def get_num_threads(self): - """Return the number of threads used by this process.""" - return self._platform_impl.get_process_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). - """ - return self._platform_impl.get_process_threads() - - def get_children(self): - """Return the children of this process as a list of Process - objects. - """ - if not self.is_running(): - name = self._platform_impl._process_name - raise NoSuchProcess(self.pid, name) - retlist = [] - for proc in process_iter(): - try: - if proc.ppid == self.pid: - retlist.append(proc) - except NoSuchProcess: - pass - return retlist - - def get_cpu_percent(self, interval=0.1): - """Return a float representing the current 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. - In this case is recommended for accuracy that this function be - called with at least 0.1 seconds between calls. - """ - blocking = interval is not None and interval > 0.0 - if blocking: - st1 = sum(cpu_times()) - pt1 = self._platform_impl.get_cpu_times() - time.sleep(interval) - st2 = sum(cpu_times()) - pt2 = self._platform_impl.get_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() - if st1 is None or pt1 is None: - self._last_sys_cpu_times = st2 - self._last_proc_cpu_times = pt2 - return 0.0 - - delta_proc = (pt2.user - pt1.user) + (pt2.system - pt1.system) - delta_time = st2 - st1 - # reset values for next call in case of interval == None - self._last_sys_cpu_times = st2 - self._last_proc_cpu_times = pt2 - - try: - # the utilization split between all CPUs - overall_percent = (delta_proc / delta_time) * 100 - except ZeroDivisionError: - # interval was too low - return 0.0 - # the utilization of a single CPU - single_cpu_percent = overall_percent * NUM_CPUS - # ugly hack to avoid troubles with float precision issues - 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. - """ - return self._platform_impl.get_cpu_times() - - def get_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 Windows RSS and VMS refer to "Mem Usage" and "VM Size" columns - of taskmgr.exe. - """ - return self._platform_impl.get_memory_info() - - def get_memory_percent(self): - """Compare physical system memory to process resident memory and - calculate process memory utilization as a percentage. - """ - rss = self._platform_impl.get_memory_info()[0] - try: - return (rss / float(TOTAL_PHYMEM)) * 100 - except ZeroDivisionError: - return 0.0 - - 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): - """Return TCP and UPD connections opened by process as a list - of namedtuples. - On BSD and OSX results for third party processes (!= os.getpid()) - can differ depending on user privileges. - """ - return self._platform_impl.get_connections() - - def is_running(self): - """Return whether this process is running.""" - try: - # Test for equality with another Process object based - # on pid and creation time. - # This pair is supposed to indentify a Process instance - # univocally over the time (the PID alone is not enough as - # it might refer to a process which is gone in meantime - # and its PID reused by another process). - new_self = Process(self.pid) - p1 = (self.pid, self.create_time) - p2 = (new_self.pid, new_self.create_time) - except NoSuchProcess: - return False - else: - return p1 == p2 - - def send_signal(self, sig): - """Send a signal to process (see signal module constants). - On Windows only SIGTERM is valid and is treated as an alias - for kill(). - """ - # safety measure in case the current process has been killed in - # meantime and the kernel reused its PID - if not self.is_running(): - name = self._platform_impl._process_name - raise NoSuchProcess(self.pid, name) - if os.name == 'posix': - try: - os.kill(self.pid, sig) - except OSError, err: - name = self._platform_impl._process_name - if err.errno == errno.ESRCH: - raise NoSuchProcess(self.pid, name) - if err.errno == errno.EPERM: - raise AccessDenied(self.pid, name) - raise - else: - if sig == signal.SIGTERM: - self._platform_impl.kill_process() - else: - raise ValueError("only SIGTERM is supported on Windows") - - def suspend(self): - """Suspend process execution.""" - # safety measure in case the current process has been killed in - # meantime and the kernel reused its PID - if not self.is_running(): - name = self._platform_impl._process_name - raise NoSuchProcess(self.pid, name) - # windows - if hasattr(self._platform_impl, "suspend_process"): - self._platform_impl.suspend_process() - else: - # posix - self.send_signal(signal.SIGSTOP) - - def resume(self): - """Resume process execution.""" - # safety measure in case the current process has been killed in - # meantime and the kernel reused its PID - if not self.is_running(): - name = self._platform_impl._process_name - raise NoSuchProcess(self.pid, name) - # windows - if hasattr(self._platform_impl, "resume_process"): - self._platform_impl.resume_process() - else: - # posix - self.send_signal(signal.SIGCONT) - - def terminate(self): - """Terminate the process with SIGTERM. - On Windows this is an alias for kill(). - """ - self.send_signal(signal.SIGTERM) - - def kill(self): - """Kill the current process.""" - # safety measure in case the current process has been killed in - # meantime and the kernel reused its PID - if not self.is_running(): - name = self._platform_impl._process_name - raise NoSuchProcess(self.pid, name) - if os.name == 'posix': - self.send_signal(signal.SIGKILL) - else: - self._platform_impl.kill_process() - - 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. - """ - if timeout is not None and not timeout >= 0: - raise ValueError("timeout must be a positive integer") - return self._platform_impl.process_wait(timeout) - - -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 unique interface: - - >>> import psutil - >>> from subprocess import PIPE - >>> p = psutil.Popen(["/usr/bin/python", "-c", "print 'hi'"], stdout=PIPE) - >>> p.name - 'python' - >>> p.uids - user(real=1000, effective=1000, saved=1000) - >>> p.username - 'giampaolo' - >>> p.communicate() - ('hi\n', None) - >>> p.terminate() - >>> p.wait(timeout=2) - 0 - >>> - - For method names common to both classes such as kill(), terminate() - and wait(), psutil.Process implementation takes precedence. - - For a complete documentation refers to: - http://docs.python.org/library/subprocess.html - """ - - def __init__(self, *args, **kwargs): - self.__subproc = subprocess.Popen(*args, **kwargs) - Process.__init__(self, self.__subproc.pid) - - def __dir__(self): - return list(set(dir(Popen) + dir(subprocess.Popen))) - - def __getattribute__(self, name): - try: - return object.__getattribute__(self, name) - except AttributeError: - try: - return object.__getattribute__(self.__subproc, name) - except AttributeError: - raise AttributeError("%s instance has no attribute '%s'" - %(self.__class__.__name__, name)) - -def process_iter(): - """Return an iterator yielding a Process class instances for all - running processes on the local machine. - """ - pids = get_pid_list() - for pid in pids: - try: - yield Process(pid) - except (NoSuchProcess, AccessDenied): - continue - -def get_process_list(): - """Return a list of Process class instances for all running - processes on the local machine. - """ - return list(process_iter()) - -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: - - user - - system - - idle - - nice (UNIX) - - iowait (Linux) - - irq (Linux, FreeBSD) - - softirq (Linux) - - When percpu is True return a list of nameduples 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() - else: - return _psplatform.get_system_per_cpu_times() - - -_last_cpu_times = cpu_times() -_last_per_cpu_times = cpu_times(percpu=True) - -def cpu_percent(interval=0.1, 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. - 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. - """ - global _last_cpu_times - global _last_per_cpu_times - blocking = interval is not None and interval > 0.0 - - def calculate(t1, t2): - t1_all = sum(t1) - t1_busy = t1_all - t1.idle - - t2_all = sum(t2) - t2_busy = t2_all - t2.idle - - # this usually indicates a float precision issue - if t2_busy <= t1_busy: - return 0.0 - - busy_delta = t2_busy - t1_busy - all_delta = t2_all - t1_all - busy_perc = (busy_delta / all_delta) * 100 - return round(busy_perc, 1) - - # system-wide usage - if not percpu: - if blocking: - t1 = cpu_times() - time.sleep(interval) - else: - t1 = _last_cpu_times - _last_cpu_times = cpu_times() - return calculate(t1, _last_cpu_times) - # per-cpu usage - else: - ret = [] - if blocking: - tot1 = cpu_times(percpu=True) - time.sleep(interval) - else: - tot1 = _last_per_cpu_times - _last_per_cpu_times = cpu_times(percpu=True) - for t1, t2 in zip(tot1, _last_per_cpu_times): - ret.append(calculate(t1, t2)) - return ret - -def phymem_usage(): - """Return the amount of total, used and free physical memory - on the system in bytes plus the percentage usage. - """ - return _psplatform.phymem_usage() - -def virtmem_usage(): - """Return the amount of total, used and free virtual memory - on the system in bytes plus the percentage usage. - - On Linux they match the values returned by free command line utility. - On OS X and FreeBSD they represent the same values as returned by - sysctl vm.vmtotal. On Windows they are determined by reading the - PageFile values of MEMORYSTATUSEX structure. - """ - return _psplatform.virtmem_usage() - -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) - -def disk_partitions(all=False): - """Return mounted partitions as a list of namedtuples including - device, mount point and filesystem type. - - If "all" parameter is False return physical devices only and ignore - all others. - """ - return _psplatform.disk_partitions(all) - -if hasattr(_psplatform, "network_io_counters"): - - def network_io_counters(pernic=False): - """Return network I/O statistics as a namedtuple including: - - number of bytes sent - - number of bytes received - - number of packets sent - - number of packets received - - 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. - """ - from psutil._common import ntuple_net_iostat - rawdict = _psplatform.network_io_counters() - if pernic: - for nic, fields in rawdict.iteritems(): - rawdict[nic] = ntuple_net_iostat(*fields) - return rawdict - else: - bytes_sent, bytes_recv, packets_sent, packets_recv = 0, 0, 0, 0 - for _, fields in rawdict.iteritems(): - bytes_sent += fields[0] - bytes_recv += fields[1] - packets_sent += fields[2] - packets_recv += fields[3] - return ntuple_net_iostat(bytes_sent, bytes_recv, - packets_sent, packets_recv) - -if hasattr(_psplatform, "disk_io_counters"): - - def disk_io_counters(perdisk=False): - """Return system disk I/O statistics as a namedtuple including: - - number of bytes read - - number of bytes written - - number of reads - - number of writes - - time spent reading from disk (in nanoseconds) - - time spent writing to disk (in nanoseconds) - - 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 - described above as the values. - """ - from psutil._common import ntuple_disk_iostat - rawdict = _psplatform.disk_io_counters() - if perdisk: - for disk, fields in rawdict.iteritems(): - rawdict[disk] = ntuple_disk_iostat(*fields) - return rawdict - else: - reads, writes, rbytes, wbytes, rtime, wtime = 0, 0, 0, 0, 0, 0 - for _, fields in rawdict.iteritems(): - reads += fields[0] - writes += fields[1] - rbytes += fields[2] - wbytes += fields[3] - rtime += fields[4] - wtime += fields[5] - return ntuple_disk_iostat(reads, writes, rbytes, wbytes, rtime, wtime) - - -def _deprecated(replacement): - # a decorator which can be used to mark functions as deprecated - def outer(fun): - def inner(*args, **kwargs): - msg = "psutil.%s is deprecated; use %s instead" \ - % (fun.__name__, replacement) - warnings.warn(msg, category=DeprecationWarning, stacklevel=2) - return fun(*args, **kwargs) - return inner - return outer - -# --- deprecated functions - -@_deprecated("psutil.phymem_usage") -def avail_phymem(): - return phymem_usage().free - -@_deprecated("psutil.phymem_usage") -def used_phymem(): - return phymem_usage().used - -@_deprecated("psutil.virtmem_usage") -def total_virtmem(): - return virtmem_usage().total - -@_deprecated("psutil.virtmem_usage") -def used_virtmem(): - return virtmem_usage().used - -@_deprecated("psutil.virtmem_usage") -def avail_virtmem(): - return virtmem_usage().free - -def test(): - """List info of all currently running processes emulating a - ps -aux output. - """ - import datetime - today_day = datetime.date.today() - - def get_process_info(pid): - proc = Process(pid) - user = proc.username - if os.name == 'nt' and '\\' in user: - user = user.split('\\')[1] - pid = proc.pid - cpu = round(proc.get_cpu_percent(interval=None), 1) - mem = round(proc.get_memory_percent(), 1) - rss, vsz = [x / 1024 for x in proc.get_memory_info()] - - # If process has been created today print H:M, else MonthDay - start = datetime.datetime.fromtimestamp(proc.create_time) - if start.date() == today_day: - start = start.strftime("%H:%M") - else: - start = start.strftime("%b%d") - - cputime = time.strftime("%M:%S", time.localtime(sum(proc.get_cpu_times()))) - cmd = ' '.join(proc.cmdline) - # where cmdline is not available UNIX shows process name between - # [] parentheses - if not cmd: - cmd = "[%s]" % proc.name - return "%-9s %-5s %-4s %4s %7s %7s %5s %8s %s" \ - % (user, pid, cpu, mem, vsz, rss, start, cputime, cmd) - - print "%-9s %-5s %-4s %4s %7s %7s %5s %7s %s" \ - % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "START", "TIME", "COMMAND") - pids = get_pid_list() - pids.sort() - for pid in pids: - try: - line = get_process_info(pid) - except (AccessDenied, NoSuchProcess): - pass - else: - print line - -if __name__ == "__main__": - test() - diff --git a/third_party/psutil/psutil/_common.py b/third_party/psutil/psutil/_common.py deleted file mode 100644 index e08011d..0000000 --- a/third_party/psutil/psutil/_common.py +++ /dev/null @@ -1,69 +0,0 @@ -#/usr/bin/env python -# -#$Id: _common.py 1142 2011-10-05 18:45:49Z 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. - -"""Common objects shared by all _ps* modules.""" - -from psutil._compat import namedtuple - -def usage_percent(used, total, _round=None): - """Calculate percentage usage of 'used' against 'total'.""" - try: - ret = (float(used) / total) * 100 - except ZeroDivisionError: - ret = 0 - if _round is not None: - return round(ret, _round) - 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 - -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 - - -# system -ntuple_sys_cputimes = namedtuple('cputimes', 'user nice system idle iowait irq softirq') -ntuple_sysmeminfo = namedtuple('usage', 'total used free percent') -ntuple_diskinfo = namedtuple('usage', 'total used free percent') -ntuple_partition = namedtuple('partition', 'device mountpoint fstype') -ntuple_net_iostat = namedtuple('iostat', 'bytes_sent bytes_recv packets_sent packets_recv') -ntuple_disk_iostat = namedtuple('iostat', 'read_count write_count read_bytes write_bytes read_time write_time') - -# processes -ntuple_meminfo = namedtuple('meminfo', 'rss vms') -ntuple_cputimes = namedtuple('cputimes', 'user system') -ntuple_openfile = namedtuple('openfile', 'path fd') -ntuple_connection = namedtuple('connection', 'fd family type local_address remote_address status') -ntuple_thread = namedtuple('thread', 'id user_time system_time') -ntuple_uids = namedtuple('user', 'real effective saved') -ntuple_gids = namedtuple('group', 'real effective saved') -ntuple_io = namedtuple('io', 'read_count write_count read_bytes write_bytes') -ntuple_ionice = namedtuple('ionice', 'ioclass value') diff --git a/third_party/psutil/psutil/_compat.py b/third_party/psutil/psutil/_compat.py deleted file mode 100644 index 1cac8b7..0000000 --- a/third_party/psutil/psutil/_compat.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _compat.py 1142 2011-10-05 18:45:49Z 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. - -"""Module which provides compatibility with older Python versions.""" - -__all__ = ["namedtuple", "property"] - -from operator import itemgetter as _itemgetter -from keyword import iskeyword as _iskeyword -import sys as _sys -import __builtin__ - -try: - from collections import namedtuple -except ImportError: - 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: - print template - - # Execute the template string in a temporary namespace - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - _property=property, _tuple=tuple) - try: - exec template in namespace - except SyntaxError, e: - 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 - - -# dirty hack to support property.setter on python < 2.6 -property = property - -if not hasattr(property, "setter"): - - class property(property): - - def __init__(self, fget, *args, **kwargs): - self.__doc__ = fget.__doc__ - super(property, self).__init__(fget, *args, **kwargs) - - def setter(self, fset): - cls_ns = _sys._getframe(1).f_locals - for k, v in cls_ns.iteritems(): - if v == self: - propname = k - break - cls_ns[propname] = property(self.fget, fset, - self.fdel, self.__doc__) - return cls_ns[propname] - - def deleter(self, fdel): - cls_ns = _sys._getframe(1).f_locals - for k, v in cls_ns.iteritems(): - if v == self: - propname = k - break - cls_ns[propname] = property(self.fget, self.fset, - fdel, self.__doc__) - return cls_ns[propname] - - __builtin__.property = property - diff --git a/third_party/psutil/psutil/_psbsd.py b/third_party/psutil/psutil/_psbsd.py deleted file mode 100644 index b437a6a..0000000 --- a/third_party/psutil/psutil/_psbsd.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _psbsd.py 1142 2011-10-05 18:45:49Z 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. - -"""FreeBSD platform implementation.""" - -import errno -import os - -import _psutil_bsd -import _psutil_posix -import _psposix -from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired -from psutil._compat import namedtuple -from psutil._common import * - -__extra__all__ = [] - -# --- constants - -NUM_CPUS = _psutil_bsd.get_num_cpus() -BOOT_TIME = _psutil_bsd.get_system_boot_time() -_TERMINAL_MAP = _psposix._get_terminal_map() -_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle irq') - -# --- public functions - -def phymem_usage(): - """Physical system memory as a (total, used, free) tuple.""" - total = _psutil_bsd.get_total_phymem() - free = _psutil_bsd.get_avail_phymem() - used = total - free - # XXX check out whether we have to do the same math we do on Linux - percent = usage_percent(used, total, _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - -def virtmem_usage(): - """Virtual system memory as a (total, used, free) tuple.""" - total = _psutil_bsd.get_total_virtmem() - free = _psutil_bsd.get_avail_virtmem() - used = total - free - percent = usage_percent(used, total, _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - -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 - -def disk_partitions(all=False): - retlist = [] - partitions = _psutil_bsd.get_disk_partitions() - for partition in partitions: - device, mountpoint, fstype = partition - if device == 'none': - device = '' - if not all: - if not os.path.isabs(device) \ - or not os.path.exists(device): - continue - ntuple = ntuple_partition(device, mountpoint, fstype) - retlist.append(ntuple) - return retlist - -get_pid_list = _psutil_bsd.get_pid_list -pid_exists = _psposix.pid_exists -get_disk_usage = _psposix.get_disk_usage -network_io_counters = _psutil_osx.get_network_io_counters - - -def wrap_exceptions(method): - """Call method(self, pid) into a try/except clause so that if an - OSError "No such process" exception is raised we assume the process - has died and raise psutil.NoSuchProcess instead. - """ - def wrapper(self, *args, **kwargs): - try: - return method(self, *args, **kwargs) - except OSError, err: - if err.errno == errno.ESRCH: - raise NoSuchProcess(self.pid, self._process_name) - if err.errno in (errno.EPERM, errno.EACCES): - raise AccessDenied(self.pid, self._process_name) - raise - 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"] - - 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_bsd.get_process_name(self.pid) - - @wrap_exceptions - def get_process_exe(self): - """Return process executable pathname.""" - return _psutil_bsd.get_process_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) - - @wrap_exceptions - def get_process_terminal(self): - tty_nr = _psutil_bsd.get_process_tty_nr(self.pid) - try: - return _TERMINAL_MAP[tty_nr] - except KeyError: - return None - - @wrap_exceptions - def get_process_ppid(self): - """Return process parent pid.""" - return _psutil_bsd.get_process_ppid(self.pid) - - @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 ntuple_uids(real, effective, saved) - - @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 ntuple_gids(real, effective, saved) - - @wrap_exceptions - def get_cpu_times(self): - """return a tuple containing process user/kernel time.""" - user, system = _psutil_bsd.get_cpu_times(self.pid) - return ntuple_cputimes(user, system) - - @wrap_exceptions - def get_memory_info(self): - """Return a tuple with the process' RSS and VMS size.""" - rss, vms = _psutil_bsd.get_memory_info(self.pid) - return ntuple_meminfo(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) - - @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) - - @wrap_exceptions - def get_process_threads(self): - """Return the number of threads belonging to the process.""" - rawlist = _psutil_bsd.get_process_threads(self.pid) - retlist = [] - for thread_id, utime, stime in rawlist: - ntuple = ntuple_thread(thread_id, utime, stime) - retlist.append(ntuple) - return retlist - - def get_open_files(self): - """Return files opened by process by parsing lsof output.""" - lsof = _psposix.LsofParser(self.pid, self._process_name) - return lsof.get_process_open_files() - - def get_connections(self): - """Return network connections opened by a process as a list of - namedtuples by parsing lsof output. - """ - lsof = _psposix.LsofParser(self.pid, self._process_name) - return lsof.get_process_connections() - - @wrap_exceptions - def process_wait(self, timeout=None): - try: - return _psposix.wait_pid(self.pid, timeout) - except TimeoutExpired: - raise TimeoutExpired(self.pid, self._process_name) - - @wrap_exceptions - def get_process_nice(self): - return _psutil_posix.getpriority(self.pid) - - @wrap_exceptions - def set_process_nice(self, value): - return _psutil_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, "?") - - @wrap_exceptions - def get_process_io_counters(self): - rc, wc, rb, wb = _psutil_bsd.get_process_io_counters(self.pid) - return ntuple_io(rc, wc, rb, wb) diff --git a/third_party/psutil/psutil/_pslinux.py b/third_party/psutil/psutil/_pslinux.py deleted file mode 100644 index 443b6ad..0000000 --- a/third_party/psutil/psutil/_pslinux.py +++ /dev/null @@ -1,751 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _pslinux.py 1142 2011-10-05 18:45:49Z 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. - -"""Linux platform implementation.""" - -import os -import errno -import socket -import struct -import sys -import base64 -import re - -import _psutil_posix -import _psutil_linux -from psutil import _psposix -from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired -from psutil._common import * - -__extra__all__ = [ - "IOPRIO_CLASS_NONE", "IOPRIO_CLASS_RT", "IOPRIO_CLASS_BE", - "IOPRIO_CLASS_IDLE", - "phymem_buffers", "cached_phymem"] - - -def _get_boot_time(): - """Return system boot time (epoch in seconds)""" - f = open('/proc/stat', 'r') - try: - for line in f: - if line.startswith('btime'): - return float(line.strip().split()[1]) - raise RuntimeError("line not found") - finally: - f.close() - -def _get_num_cpus(): - """Return the number of CPUs on the system""" - num = 0 - f = open('/proc/cpuinfo', 'r') - try: - lines = f.readlines() - finally: - f.close() - for line in lines: - if line.lower().startswith('processor'): - num += 1 - - # unknown format (e.g. amrel/sparc architectures), see: - # http://code.google.com/p/psutil/issues/detail?id=200 - 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("can't determine number of CPUs") - return num - - -# Number of clock ticks per second -_CLOCK_TICKS = os.sysconf(os.sysconf_names["SC_CLK_TCK"]) -_TERMINAL_MAP = _psposix._get_terminal_map() -BOOT_TIME = _get_boot_time() -NUM_CPUS = _get_num_cpus() -# 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 - -# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h -_TCP_STATES_TABLE = {"01" : "ESTABLISHED", - "02" : "SYN_SENT", - "03" : "SYN_RECV", - "04" : "FIN_WAIT1", - "05" : "FIN_WAIT2", - "06" : "TIME_WAIT", - "07" : "CLOSE", - "08" : "CLOSE_WAIT", - "09" : "LAST_ACK", - "0A" : "LISTEN", - "0B" : "CLOSING" - } - -# --- system memory functions - -def cached_phymem(): - """Return the amount of cached memory on the system, in bytes. - This reflects the "cached" column of free command line utility. - """ - f = open('/proc/meminfo', 'r') - try: - for line in f: - if line.startswith('Cached:'): - return int(line.split()[1]) * 1024 - raise RuntimeError("line not found") - finally: - f.close() - -def phymem_buffers(): - """Return the amount of physical memory buffers used by the - kernel in bytes. - This reflects the "buffers" column of free command line utility. - """ - f = open('/proc/meminfo', 'r') - try: - for line in f: - if line.startswith('Buffers:'): - return int(line.split()[1]) * 1024 - raise RuntimeError("line not found") - finally: - f.close() - -def phymem_usage(): - # total, used and free values are matched against free cmdline utility - # the percentage matches top/htop and gnome-system-monitor - f = open('/proc/meminfo', 'r') - try: - total = free = buffers = cached = None - for line in f: - if line.startswith('MemTotal:'): - total = int(line.split()[1]) * 1024 - elif line.startswith('MemFree:'): - free = int(line.split()[1]) * 1024 - elif line.startswith('Buffers:'): - buffers = int(line.split()[1]) * 1024 - elif line.startswith('Cached:'): - cached = int(line.split()[1]) * 1024 - break - used = total - free - percent = usage_percent(total - (free + buffers + cached), total, - _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - finally: - f.close() - - -def virtmem_usage(): - f = open('/proc/meminfo', 'r') - try: - total = free = None - for line in f: - if line.startswith('SwapTotal:'): - total = int(line.split()[1]) * 1024 - elif line.startswith('SwapFree:'): - free = int(line.split()[1]) * 1024 - if total is not None and free is not None: - break - assert total is not None and free is not None - used = total - free - percent = usage_percent(used, total, _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - finally: - f.close() - - -# --- system CPU functions - -def get_system_cpu_times(): - """Return a named tuple representing the following CPU times: - user, nice, system, idle, iowait, irq, softirq. - """ - f = open('/proc/stat', 'r') - try: - values = f.readline().split() - finally: - f.close() - - values = values[1:8] - values = tuple([float(x) / _CLOCK_TICKS for x in values]) - return ntuple_sys_cputimes(*values[:7]) - -def get_system_per_cpu_times(): - """Return a list of namedtuple representing the CPU times - for every CPU available on the system. - """ - cpus = [] - f = open('/proc/stat', 'r') - # get rid of the first line who refers to system wide CPU stats - try: - f.readline() - for line in f.readlines(): - if line.startswith('cpu'): - values = line.split()[1:8] - values = tuple([float(x) / _CLOCK_TICKS for x in values]) - entry = ntuple_sys_cputimes(*values[:7]) - 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") - try: - for line in f: - if not line.startswith("nodev"): - phydevs.append(line.strip()) - finally: - f.close() - - retlist = [] - partitions = _psutil_linux.get_disk_partitions() - for partition in partitions: - device, mountpoint, fstype = partition - if device == 'none': - device = '' - if not all: - if device == '' or fstype not in phydevs: - continue - ntuple = ntuple_partition(device, mountpoint, fstype) - retlist.append(ntuple) - return retlist - -get_disk_usage = _psposix.get_disk_usage - -# --- process functions - -def get_pid_list(): - """Returns a list of PIDs currently running on the system.""" - pids = [int(x) for x in os.listdir('/proc') if x.isdigit()] - return pids - -def pid_exists(pid): - """Check For the existence of a unix pid.""" - return _psposix.pid_exists(pid) - -def network_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: - lines = f.readlines() - finally: - f.close() - - retdict = {} - for line in lines[2:]: - fields = line.split() - name = fields[0][:-1] - bytes_recv = int(fields[1]) - packets_recv = int(fields[2]) - bytes_sent = int(fields[9]) - packets_sent = int(fields[10]) - retdict[name] = (bytes_sent, bytes_recv, packets_sent, packets_recv) - return retdict - -def disk_io_counters(): - """Return disk I/O statistics for every disk installed on the - system as a dict of raw tuples. - """ - # man iostat states that sectors are equivalent with blocks and - # have a size of 512 bytes since 2.4 kernels. This value is - # needed to calculate the amount of disk I/O in bytes. - SECTOR_SIZE = 512 - - # determine partitions we want to look for - partitions = [] - f = open("/proc/partitions", "r") - try: - lines = f.readlines()[2:] - finally: - f.close() - for line in lines: - _, _, _, name = line.split() - if name[-1].isdigit(): - partitions.append(name) - # - retdict = {} - f = open("/proc/diskstats", "r") - try: - lines = f.readlines() - finally: - f.close() - for line in lines: - _, _, name, reads, _, rbytes, rtime, writes, _, wbytes, wtime = \ - line.split()[:11] - if name in partitions: - rbytes = int(rbytes) * SECTOR_SIZE - wbytes = int(wbytes) * SECTOR_SIZE - reads = int(reads) - writes = int(writes) - # TODO: times are expressed in milliseconds while OSX/BSD has - # these expressed in nanoseconds; figure this out. - rtime = int(rtime) - wtime = int(wtime) - retdict[name] = (reads, writes, rbytes, wbytes, rtime, wtime) - 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} - -# --- decorators - -def wrap_exceptions(callable): - """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 callable(self, *args, **kwargs) - except (OSError, IOError), err: - # ENOENT (no such file or directory) gets raised on open(). - # ESRCH (no such process) can get raised on read() if - # process is gone in meantime. - if err.errno in (errno.ENOENT, errno.ESRCH): - raise NoSuchProcess(self.pid, self._process_name) - if err.errno in (errno.EPERM, errno.EACCES): - raise AccessDenied(self.pid, self._process_name) - raise - return wrapper - - -class Process(object): - """Linux process implementation.""" - - __slots__ = ["pid", "_process_name"] - - def __init__(self, pid): - self.pid = pid - self._process_name = None - - @wrap_exceptions - def get_process_name(self): - f = open("/proc/%s/stat" % self.pid) - try: - name = f.read().split(' ')[1].replace('(', '').replace(')', '') - finally: - f.close() - # XXX - gets changed later and probably needs refactoring - return name - - def get_process_exe(self): - if self.pid in (0, 2): - raise AccessDenied(self.pid, self._process_name) - try: - exe = os.readlink("/proc/%s/exe" % self.pid) - except (OSError, IOError), err: - if err.errno == errno.ENOENT: - # no such file error; might be raised also if the - # path actually exists for system processes with - # low pids (about 0-20) - if os.path.lexists("/proc/%s/exe" % self.pid): - return "" - else: - # ok, it is a process which has gone away - raise NoSuchProcess(self.pid, self._process_name) - if err.errno in (errno.EPERM, errno.EACCES): - raise AccessDenied(self.pid, self._process_name) - raise - - # readlink() might return paths containing null bytes causing - # problems when used with other fs-related functions (os.*, - # open(), ...) - exe = exe.replace('\x00', '') - # It seems symlinks can point to a deleted/invalid location - # (this usually happens with "pulseaudio" process). - # However, if we had permissions to execute readlink() it's - # likely that we'll be able to figure out exe from argv[0] - # later on. - if exe.endswith(" (deleted)") and not os.path.isfile(exe): - return "" - return exe - - @wrap_exceptions - def get_process_cmdline(self): - f = open("/proc/%s/cmdline" % self.pid) - try: - # return the args as a list - return [x for x in f.read().split('\x00') if x] - finally: - f.close() - - @wrap_exceptions - def get_process_terminal(self): - f = open("/proc/%s/stat" % self.pid) - try: - tty_nr = int(f.read().split(' ')[6]) - finally: - f.close() - try: - return _TERMINAL_MAP[tty_nr] - except KeyError: - return None - - @wrap_exceptions - def get_process_io_counters(self): - f = open("/proc/%s/io" % self.pid) - try: - for line in f: - if line.startswith("rchar"): - read_count = int(line.split()[1]) - elif line.startswith("wchar"): - write_count = int(line.split()[1]) - elif line.startswith("read_bytes"): - read_bytes = int(line.split()[1]) - elif line.startswith("write_bytes"): - write_bytes = int(line.split()[1]) - return ntuple_io(read_count, write_count, read_bytes, write_bytes) - finally: - f.close() - - @wrap_exceptions - def get_cpu_times(self): - f = open("/proc/%s/stat" % self.pid) - 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 - return ntuple_cputimes(utime, stime) - - @wrap_exceptions - def process_wait(self, timeout=None): - try: - return _psposix.wait_pid(self.pid, timeout) - except TimeoutExpired: - raise TimeoutExpired(self.pid, self._process_name) - - @wrap_exceptions - def get_process_create_time(self): - f = open("/proc/%s/stat" % self.pid) - try: - st = f.read().strip() - finally: - f.close() - # ignore the first two values ("pid (exe)") - st = st[st.find(')') + 2:] - values = st.split(' ') - # 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 - - @wrap_exceptions - def get_memory_info(self): - f = open("/proc/%s/status" % self.pid) - try: - virtual_size = 0 - resident_size = 0 - _flag = False - for line in f: - if (not _flag) and line.startswith("VmSize:"): - virtual_size = int(line.split()[1]) * 1024 - _flag = True - elif line.startswith("VmRSS"): - resident_size = int(line.split()[1]) * 1024 - break - return ntuple_meminfo(resident_size, virtual_size) - finally: - f.close() - - @wrap_exceptions - def get_process_cwd(self): - # readlink() might return paths containing null bytes causing - # problems when used with other fs-related functions (os.*, - # open(), ...) - path = os.readlink("/proc/%s/cwd" % self.pid) - return path.replace('\x00', '') - - @wrap_exceptions - def get_process_num_threads(self): - f = open("/proc/%s/status" % self.pid) - try: - for line in f: - if line.startswith("Threads:"): - return int(line.split()[1]) - raise RuntimeError("line not found") - finally: - f.close() - - @wrap_exceptions - def get_process_threads(self): - thread_ids = os.listdir("/proc/%s/task" % self.pid) - thread_ids.sort() - retlist = [] - for thread_id in thread_ids: - try: - f = open("/proc/%s/task/%s/stat" % (self.pid, thread_id)) - except (OSError, IOError), err: - if err.errno == errno.ENOENT: - # no such file or directory; it means thread - # disappeared on us - 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 = ntuple_thread(int(thread_id), utime, stime) - retlist.append(ntuple) - return retlist - - @wrap_exceptions - def get_process_nice(self): - #f = open('/proc/%s/stat' % self.pid, 'r') - #try: - # data = f.read() - # return int(data.split()[18]) - #finally: - # f.close() - - # Use C implementation - return _psutil_posix.getpriority(self.pid) - - @wrap_exceptions - def set_process_nice(self, value): - return _psutil_posix.setpriority(self.pid, value) - - # only starting from kernel 2.6.13 - if hasattr(_psutil_linux, "ioprio_get"): - - @wrap_exceptions - def get_process_ionice(self): - ioclass, value = _psutil_linux.ioprio_get(self.pid) - return ntuple_ionice(ioclass, value) - - @wrap_exceptions - def set_process_ionice(self, ioclass, value): - if ioclass in (IOPRIO_CLASS_NONE, None): - if value: - raise ValueError("can't specify value with IOPRIO_CLASS_NONE") - ioclass = IOPRIO_CLASS_NONE - value = 0 - if ioclass in (IOPRIO_CLASS_RT, IOPRIO_CLASS_BE): - if value is None: - value = 4 - elif ioclass == IOPRIO_CLASS_IDLE: - if value: - raise ValueError("can't specify value with IOPRIO_CLASS_IDLE") - 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) - - @wrap_exceptions - def get_process_status(self): - f = open("/proc/%s/status" % self.pid) - try: - for line in f: - if line.startswith("State:"): - letter = line.split()[1] - if letter in _status_map: - return _status_map[letter] - return constant(-1, '?') - finally: - f.close() - - @wrap_exceptions - def get_open_files(self): - retlist = [] - files = os.listdir("/proc/%s/fd" % self.pid) - for fd in files: - file = "/proc/%s/fd/%s" % (self.pid, fd) - if os.path.islink(file): - file = os.readlink(file) - if file.startswith("socket:["): - continue - if file.startswith("pipe:["): - continue - if file == "[]": - continue - if os.path.isfile(file) and not file in retlist: - ntuple = ntuple_openfile(file, int(fd)) - retlist.append(ntuple) - return retlist - - @wrap_exceptions - def get_connections(self): - inodes = {} - # os.listdir() is gonna raise a lot of access denied - # exceptions in case of unprivileged user; that's fine: - # lsof does the same so it's unlikely that we can to better. - for fd in os.listdir("/proc/%s/fd" % self.pid): - try: - inode = os.readlink("/proc/%s/fd/%s" % (self.pid, fd)) - except OSError: - continue - if inode.startswith('socket:['): - # the process is using a socket - inode = inode[8:][:-1] - inodes[inode] = fd - - if not inodes: - # no connections for this process - return [] - - def process(file, family, _type): - retlist = [] - f = open(file) - try: - f.readline() # skip the first line - for line in f: - _, 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 = ntuple_connection(fd, family, _type, laddr, - raddr, status) - retlist.append(conn) - return retlist - finally: - f.close() - - tcp4 = process("/proc/net/tcp", socket.AF_INET, socket.SOCK_STREAM) - udp4 = process("/proc/net/udp", socket.AF_INET, socket.SOCK_DGRAM) - try: - tcp6 = process("/proc/net/tcp6", socket.AF_INET6, socket.SOCK_STREAM) - udp6 = process("/proc/net/udp6", socket.AF_INET6, socket.SOCK_DGRAM) - except IOError, err: - if err.errno == errno.ENOENT: - # IPv6 is not supported on this platform - tcp6 = udp6 = [] - else: - raise - return tcp4 + tcp6 + udp4 + udp6 - -# --- lsof implementation -# -# def get_connections(self): -# lsof = _psposix.LsofParser(self.pid, self._process_name) -# return lsof.get_process_connections() - - @wrap_exceptions - def get_process_ppid(self): - f = open("/proc/%s/status" % self.pid) - try: - for line in f: - if line.startswith("PPid:"): - # PPid: nnnn - return int(line.split()[1]) - raise RuntimeError("line not found") - finally: - f.close() - - @wrap_exceptions - def get_process_uids(self): - f = open("/proc/%s/status" % self.pid) - try: - for line in f: - if line.startswith('Uid:'): - _, real, effective, saved, fs = line.split() - return ntuple_uids(int(real), int(effective), int(saved)) - raise RuntimeError("line not found") - finally: - f.close() - - @wrap_exceptions - def get_process_gids(self): - f = open("/proc/%s/status" % self.pid) - try: - for line in f: - if line.startswith('Gid:'): - _, real, effective, saved, fs = line.split() - return ntuple_gids(int(real), int(effective), int(saved)) - raise RuntimeError("line not found") - finally: - f.close() - - @staticmethod - def _decode_address(addr, family): - """Accept an "ip:port" address as displayed in /proc/net/* - and convert it into a human readable form, like: - - "0500000A:0016" -> ("10.0.0.5", 22) - "0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521) - - The IP address portion is a little or big endian four-byte - hexadecimal number; that is, the least significant byte is listed - first, so we need to reverse the order of the bytes to convert it - to an IP address. - The port is represented as a two-byte hexadecimal number. - - Reference: - http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html - """ - ip, port = addr.split(':') - port = int(port, 16) - if sys.version_info >= (3,): - ip = ip.encode('ascii') - # this usually refers to a local socket in listen mode with - # no end-points connected - if not port: - return () - if family == socket.AF_INET: - # see: http://code.google.com/p/psutil/issues/detail?id=201 - if sys.byteorder == 'little': - ip = socket.inet_ntop(family, base64.b16decode(ip)[::-1]) - else: - ip = socket.inet_ntop(family, base64.b16decode(ip)) - else: # IPv6 - # old version - let's keep it, just in case... - #ip = ip.decode('hex') - #return socket.inet_ntop(socket.AF_INET6, - # ''.join(ip[i:i+4][::-1] for i in xrange(0, 16, 4))) - ip = base64.b16decode(ip) - # see: http://code.google.com/p/psutil/issues/detail?id=201 - if sys.byteorder == 'little': - ip = socket.inet_ntop(socket.AF_INET6, - struct.pack('>4I', *struct.unpack('<4I', ip))) - else: - ip = socket.inet_ntop(socket.AF_INET6, - struct.pack('<4I', *struct.unpack('<4I', ip))) - return (ip, port) diff --git a/third_party/psutil/psutil/_psmswindows.py b/third_party/psutil/psutil/_psmswindows.py deleted file mode 100644 index 81ffad7..0000000 --- a/third_party/psutil/psutil/_psmswindows.py +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _psmswindows.py 1142 2011-10-05 18:45:49Z 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. - -"""Windows platform implementation.""" - -import errno -import os -import sys -import platform - -import _psutil_mswindows -from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired -from psutil._compat import namedtuple -from psutil._common import * - -# 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) - -NUM_CPUS = _psutil_mswindows.get_num_cpus() -BOOT_TIME = _psutil_mswindows.get_system_uptime() -_WIN2000 = platform.win32_ver()[0] == '2000' -ERROR_ACCESS_DENIED = 5 -WAIT_TIMEOUT = 0x00000102 # 258 in decimal - -# 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) - -# --- public functions - -def phymem_usage(): - """Physical system memory as a (total, used, free) tuple.""" - all = _psutil_mswindows.get_system_phymem() - total, free, total_pagef, avail_pagef, total_virt, free_virt, percent = all - used = total - free - return ntuple_sysmeminfo(total, used, free, round(percent, 1)) - -def virtmem_usage(): - """Virtual system memory as a (total, used, free) tuple.""" - all = _psutil_mswindows.get_system_phymem() - total_virt = all[4] - free_virt = all[5] - used = total_virt - free_virt - percent = usage_percent(used, total_virt, _round=1) - return ntuple_sysmeminfo(total_virt, used, free_virt, percent) - -def get_disk_usage(path): - """Return disk usage associated with path.""" - try: - total, free = _psutil_mswindows.get_disk_usage(path) - except WindowsError, err: - 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 ntuple_diskinfo(total, used, free, percent) - -def disk_partitions(all): - """Return disk partitions.""" - retlist = [] - drive_letters = _psutil_mswindows.win32_GetLogicalDriveStrings() - for letter in drive_letters: - mountpoint = letter - type = _psutil_mswindows.win32_GetDriveType(letter) - if not os.path.exists(mountpoint): - # usually a CD-ROM device with no disk inserted - mountpoint = "" - if not all: - if type not in ('cdrom', 'fixed', 'removable'): - continue - if not mountpoint: - continue - ntuple = ntuple_partition(letter, mountpoint, type) - retlist.append(ntuple) - return retlist - - -_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 - -get_pid_list = _psutil_mswindows.get_pid_list -pid_exists = _psutil_mswindows.pid_exists - -# --- decorator - -def wrap_exceptions(callable): - """Call callable into a try/except clause so that if a - WindowsError 5 AccessDenied exception is raised we translate it - into psutil.AccessDenied - """ - def wrapper(self, *args, **kwargs): - try: - return callable(self, *args, **kwargs) - except OSError, err: - if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED): - raise AccessDenied(self.pid, self._process_name) - if err.errno == errno.ESRCH: - raise NoSuchProcess(self.pid, self._process_name) - raise - 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) - - def get_process_exe(self): - # no such thing as "exe" on Windows; it will maybe be determined - # later from cmdline[0] - if not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._process_name) - if self.pid in (0, 4): - raise AccessDenied(self.pid, self._process_name) - return "" - - @wrap_exceptions - def get_process_cmdline(self): - """Return process cmdline as a list of arguments.""" - return _psutil_mswindows.get_process_cmdline(self.pid) - - @wrap_exceptions - def get_process_ppid(self): - """Return process parent pid.""" - return _psutil_mswindows.get_process_ppid(self.pid) - - @wrap_exceptions - def get_memory_info(self): - """Returns a tuple or RSS/VMS memory usage in bytes.""" - # special case for 0 (kernel processes) PID - if self.pid == 0: - return ntuple_meminfo(0, 0) - rss, vms = _psutil_mswindows.get_memory_info(self.pid) - return ntuple_meminfo(rss, vms) - - @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) or self.pid == 8 and _WIN2000: - return 'NT AUTHORITY\\SYSTEM' - return _psutil_mswindows.get_process_username(self.pid); - - @wrap_exceptions - def get_process_create_time(self): - # special case for kernel process PIDs; return system boot time - if self.pid in (0, 4) or self.pid == 8 and _WIN2000: - return BOOT_TIME - return _psutil_mswindows.get_process_create_time(self.pid) - - @wrap_exceptions - def get_process_num_threads(self): - return _psutil_mswindows.get_process_num_threads(self.pid) - - @wrap_exceptions - def get_process_threads(self): - rawlist = _psutil_mswindows.get_process_threads(self.pid) - retlist = [] - for thread_id, utime, stime in rawlist: - ntuple = ntuple_thread(thread_id, utime, stime) - retlist.append(ntuple) - return retlist - - @wrap_exceptions - def get_cpu_times(self): - user, system = _psutil_mswindows.get_process_cpu_times(self.pid) - return ntuple_cputimes(user, system) - - @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) or self.pid == 8 and _WIN2000: - 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) or self.pid == 8 and _WIN2000: - 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: - if sys.version_info >= (3,): - file = file.decode('utf8') - if file.startswith('\\Device\\'): - rawdrive = '\\'.join(file.split('\\')[:3]) - driveletter = _psutil_mswindows.win32_QueryDosDevice(rawdrive) - file = file.replace(rawdrive, driveletter) - if os.path.isfile(file) and file not in retlist: - ntuple = ntuple_openfile(file, -1) - retlist.append(ntuple) - return retlist - - @wrap_exceptions - def get_connections(self): - retlist = _psutil_mswindows.get_process_connections(self.pid) - return [ntuple_connection(*conn) for conn in retlist] - - @wrap_exceptions - def get_process_nice(self): - return _psutil_mswindows.get_process_priority(self.pid) - - @wrap_exceptions - def set_process_nice(self, value): - return _psutil_mswindows.set_process_priority(self.pid, value) - - @wrap_exceptions - def get_process_io_counters(self): - rc, wc, rb, wb =_psutil_mswindows.get_process_io_counters(self.pid) - return ntuple_io(rc, wc, rb, wb) - - @wrap_exceptions - def get_process_status(self): - suspended = _psutil_mswindows.is_process_suspended(self.pid) - if suspended: - return STATUS_STOPPED - else: - return STATUS_RUNNING diff --git a/third_party/psutil/psutil/_psosx.py b/third_party/psutil/psutil/_psosx.py deleted file mode 100644 index 543124c..0000000 --- a/third_party/psutil/psutil/_psosx.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _psosx.py 1142 2011-10-05 18:45:49Z 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. - -"""OSX platform implementation.""" - -import errno -import os - -import _psutil_osx -import _psutil_posix -import _psposix -from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired -from psutil._compat import namedtuple -from psutil._common import * - -__extra__all__ = [] - -# --- constants - -NUM_CPUS = _psutil_osx.get_num_cpus() -BOOT_TIME = _psutil_osx.get_system_boot_time() -_TERMINAL_MAP = _psposix._get_terminal_map() -_cputimes_ntuple = namedtuple('cputimes', 'user nice system idle') - -# --- functions - -def phymem_usage(): - """Physical system memory as a (total, used, free) tuple.""" - total = _psutil_osx.get_total_phymem() - free = _psutil_osx.get_avail_phymem() - used = total - free - percent = usage_percent(used, total, _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - -def virtmem_usage(): - """Virtual system memory as a (total, used, free) tuple.""" - total = _psutil_osx.get_total_virtmem() - free = _psutil_osx.get_avail_virtmem() - used = total - free - percent = usage_percent(used, total, _round=1) - return ntuple_sysmeminfo(total, used, free, percent) - -def get_system_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) - -def get_system_per_cpu_times(): - """Return system CPU times as a named tuple""" - ret = [] - for cpu_t in _psutil_osx.get_system_per_cpu_times(): - user, nice, system, idle = cpu_t - item = _cputimes_ntuple(user, nice, system, idle) - ret.append(item) - return ret - -def disk_partitions(all=False): - retlist = [] - partitions = _psutil_osx.get_disk_partitions() - for partition in partitions: - device, mountpoint, fstype = partition - if device == 'none': - device = '' - if not all: - if not os.path.isabs(device) \ - or not os.path.exists(device): - continue - ntuple = ntuple_partition(device, mountpoint, fstype) - retlist.append(ntuple) - return retlist - -get_pid_list = _psutil_osx.get_pid_list -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 - -# --- decorator - -def wrap_exceptions(callable): - """Call callable into a try/except clause so that if an - OSError EPERM exception is raised we translate it into - psutil.AccessDenied. - """ - def wrapper(self, *args, **kwargs): - try: - return callable(self, *args, **kwargs) - except OSError, err: - if err.errno == errno.ESRCH: - raise NoSuchProcess(self.pid, self._process_name) - if err.errno in (errno.EPERM, errno.EACCES): - raise AccessDenied(self.pid, self._process_name) - raise - 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"] - - 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_osx.get_process_name(self.pid) - - def get_process_exe(self): - # no such thing as "exe" on OS X; it will maybe be determined - # later from cmdline[0] - if not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._process_name) - return "" - - @wrap_exceptions - def get_process_cmdline(self): - """Return process cmdline as a list of arguments.""" - if not pid_exists(self.pid): - raise NoSuchProcess(self.pid, self._process_name) - return _psutil_osx.get_process_cmdline(self.pid) - - @wrap_exceptions - def get_process_ppid(self): - """Return process parent pid.""" - return _psutil_osx.get_process_ppid(self.pid) - - @wrap_exceptions - def get_process_uids(self): - real, effective, saved = _psutil_osx.get_process_uids(self.pid) - return ntuple_uids(real, effective, saved) - - @wrap_exceptions - def get_process_gids(self): - real, effective, saved = _psutil_osx.get_process_gids(self.pid) - return ntuple_gids(real, effective, saved) - - @wrap_exceptions - def get_process_terminal(self): - tty_nr = _psutil_osx.get_process_tty_nr(self.pid) - try: - return _TERMINAL_MAP[tty_nr] - except KeyError: - return None - - @wrap_exceptions - def get_memory_info(self): - """Return a tuple with the process' RSS and VMS size.""" - rss, vms = _psutil_osx.get_memory_info(self.pid) - return ntuple_meminfo(rss, vms) - - @wrap_exceptions - def get_cpu_times(self): - user, system = _psutil_osx.get_cpu_times(self.pid) - return ntuple_cputimes(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) - - @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) - - @wrap_exceptions - def get_open_files(self): - """Return files opened by process.""" - if self.pid == 0: - raise AccessDenied(self.pid, self._process_name) - files = [] - rawlist = _psutil_osx.get_process_open_files(self.pid) - for path, fd in rawlist: - if os.path.isfile(path): - ntuple = ntuple_openfile(path, fd) - files.append(ntuple) - return files - - @wrap_exceptions - def get_connections(self): - """Return etwork connections opened by a process as a list of - namedtuples.""" - retlist = _psutil_osx.get_process_connections(self.pid) - return [ntuple_connection(*conn) for conn in retlist] - - @wrap_exceptions - def process_wait(self, timeout=None): - try: - return _psposix.wait_pid(self.pid, timeout) - except TimeoutExpired: - raise TimeoutExpired(self.pid, self._process_name) - - @wrap_exceptions - def get_process_nice(self): - return _psutil_posix.getpriority(self.pid) - - @wrap_exceptions - def set_process_nice(self, value): - return _psutil_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, "?") - - @wrap_exceptions - def get_process_threads(self): - """Return the number of threads belonging to the process.""" - rawlist = _psutil_osx.get_process_threads(self.pid) - retlist = [] - for thread_id, utime, stime in rawlist: - ntuple = ntuple_thread(thread_id, utime, stime) - retlist.append(ntuple) - return retlist diff --git a/third_party/psutil/psutil/_psposix.py b/third_party/psutil/psutil/_psposix.py deleted file mode 100644 index 08cc268..0000000 --- a/third_party/psutil/psutil/_psposix.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _psposix.py 1142 2011-10-05 18:45:49Z 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. - -"""Routines common to all posix systems.""" - -import os -import errno -import subprocess -import psutil -import socket -import re -import sys -import warnings -import time -import glob - -from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired -from psutil._compat import namedtuple -from psutil._common import ntuple_diskinfo, usage_percent - - -def pid_exists(pid): - """Check whether pid exists in the current process table.""" - if pid < 0: - return False - try: - os.kill(pid, 0) - except OSError, e: - return e.errno == errno.EPERM - 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. - - If pid is not a children of os.getpid() (current process) just - waits until the process disappears and return None. - - If pid does not exist at all return None immediately. - - Raise TimeoutExpired on timeout expired. - """ - def check_timeout(): - if timeout is not None: - if time.time() >= stop_at: - raise TimeoutExpired - time.sleep(0.001) - - if timeout is not None: - waitcall = lambda: os.waitpid(pid, os.WNOHANG) - stop_at = time.time() + timeout - else: - waitcall = lambda: os.waitpid(pid, 0) - - while 1: - try: - retpid, status = waitcall() - except OSError, err: - if err.errno == errno.EINTR: - check_timeout() - continue - elif err.errno == errno.ECHILD: - # not a child of os.getpid(): poll until pid has - # disappeared and return None instead - while 1: - if pid_exists(pid): - check_timeout() - else: - return - else: - raise - else: - if retpid == 0: - check_timeout() - continue - # process exited due to a signal; return the integer of - # that signal - if os.WIFSIGNALED(status): - return os.WTERMSIG(status) - # process exited using exit(2) system call; return the - # integer exit(2) system call has been called with - elif os.WIFEXITED(status): - return os.WEXITSTATUS(status) - else: - # should never happen - raise RuntimeError("unknown process exit status") - -def get_disk_usage(path): - """Return disk usage associated with path.""" - st = os.statvfs(path) - free = (st.f_bavail * st.f_frsize) - total = (st.f_blocks * st.f_frsize) - used = (st.f_blocks - st.f_bfree) * st.f_frsize - percent = usage_percent(used, total, _round=1) - # NB: the percentage is -5% than what shown by df due to - # reserved blocks that we are currently not considering: - # http://goo.gl/sWGbH - return ntuple_diskinfo(total, used, free, percent) - -def _get_terminal_map(): - ret = {} - ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*') - for name in ls: - assert name not in ret - ret[os.stat(name).st_rdev] = name - return ret - - -class LsofParser: - """A wrapper for lsof command line utility. - Executes lsof in subprocess and parses its output. - """ - socket_table = {'TCP' : socket.SOCK_STREAM, - 'UDP' : socket.SOCK_DGRAM, - 'IPv4' : socket.AF_INET, - 'IPv6' : socket.AF_INET6} - _openfile_ntuple = namedtuple('openfile', 'path fd') - _connection_ntuple = namedtuple('connection', 'fd family type local_address ' - 'remote_address status') - - def __init__(self, pid, name): - self.pid = pid - self.process_name = name - - def get_process_open_files(self): - """Return files opened by process by parsing lsof output.""" - # Options: - # -i == network files only - # -a == ANDing of all options - # -p == process with given PID only - # -n == do not resolve IP addresses - # -P == do not resolve port numbers - # -w == suppresses warnings - # -F0nPt == (0) separate lines with "\x00" - # (n) file name - # (t) file type - # (f) file descriptr - cmd = "lsof -a -p %s -n -P -F0ftn" % self.pid - stdout = self.runcmd(cmd) - if not stdout: - return [] - files = [] - lines = stdout.split("\n") - del lines[0] # first line contains the PID - for line in lines: - if not line: - continue - line = line.strip("\x00") - fields = {} - for field in line.split("\x00"): - key, value = field[0], field[1:] - fields[key] = value - if not 't' in fields: - continue - _type = fields['t'] - fd = fields['f'] - name = fields['n'] - if 'REG' in _type and fd.isdigit(): - if not os.path.isfile(os.path.realpath(name)): - continue - ntuple = self._openfile_ntuple(name, int(fd)) - files.append(ntuple) - return files - - def get_process_connections(self): - """Return connections opened by a process by parsing lsof output.""" - # Options: - # -i == network files only - # -a == ANDing of all options - # -p == process with given PID only - # -n == do not resolve IP addresses - # -P == do not resolve port numbers - # -w == suppresses warnings - # -F0nPt == (0) separate lines with "\x00" - # (n) and show internet addresses only - # (P) protocol type (TCP, UPD, Unix) - # (t) socket family (IPv4, IPv6) - # (T) connection status - # (f) file descriptors - cmd = "lsof -p %s -i -a -F0nPtTf -n -P" % self.pid - stdout = self.runcmd(cmd) - if not stdout: - return [] - connections = [] - lines = stdout.split() - del lines[0] # first line contains the PID - for line in lines: - line = line.strip("\x00") - fields = {} - for field in line.split("\x00"): - if field.startswith('T'): - key, value = field.split('=') - else: - key, value = field[0], field[1:] - fields[key] = value - - # XXX - might trow execption; needs "continue on unsupported - # family or type" (e.g. unix sockets) - # we consider TCP and UDP sockets only - stype = fields['P'] - if stype not in self.socket_table: - continue - else: - _type = self.socket_table[fields['P']] - family = self.socket_table[fields['t']] - peers = fields['n'] - fd = int(fields['f']) - if _type == socket.SOCK_STREAM: - status = fields['TST'] - # OS X shows "CLOSED" instead of "CLOSE" so translate them - if status == "CLOSED": - status = "CLOSE" - else: - status = "" - if not '->' in peers: - local_addr = self._normaddress(peers, family) - remote_addr = () - # OS X processes e.g. SystemUIServer can return *:* for local - # address, so we return 0 and move on - if local_addr == 0: - continue - else: - local_addr, remote_addr = peers.split("->") - local_addr = self._normaddress(local_addr, family) - remote_addr = self._normaddress(remote_addr, family) - - conn = self._connection_ntuple(fd, family, _type, local_addr, - remote_addr, status) - connections.append(conn) - - return connections - - def runcmd(self, cmd): - """Expects an lsof-related command line, execute it in a - subprocess and return its output. - If something goes bad stderr is parsed and proper exceptions - raised as necessary. - """ - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if sys.version_info >= (3,): - stdout, stderr = map(lambda x: x.decode(sys.stdout.encoding), - (stdout, stderr)) - if stderr: - utility = cmd.split(' ')[0] - if self._which(utility) is None: - msg = "this functionnality requires %s command line utility " \ - "to be installed on the system" % utility - raise NotImplementedError(msg) - elif "permission denied" in stderr.lower(): - # "permission denied" can be found also in case of zombie - # processes; - p = psutil.Process(self.pid) - if not p.is_running(): - raise NoSuchProcess(self.pid, self.process_name) - raise AccessDenied(self.pid, self.process_name) - elif "lsof: warning:" in stderr.lower(): - # usually appears when lsof is run for the first time and - # complains about missing cache file in user home - warnings.warn(stderr, RuntimeWarning) - else: - # this must be considered an application bug - raise RuntimeError(stderr) - if not stdout: - p = psutil.Process(self.pid) - if not p.is_running(): - raise NoSuchProcess(self.pid, self.process_name) - return "" - return stdout - - @staticmethod - def _which(program): - """Same as UNIX which command. Return None on command not found.""" - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file - return None - - @staticmethod - def _normaddress(addr, family): - """Normalize an IP address.""" - assert family in (socket.AF_INET, socket.AF_INET6), "unsupported family" - if family == socket.AF_INET: - ip, port = addr.split(':') - else: - if "]" in addr: - ip, port = re.findall('\[([^]]+)\]:([0-9]+)', addr)[0] - else: - ip, port = addr.split(':') - if ip == '*': - if family == socket.AF_INET: - ip = "0.0.0.0" - elif family == socket.AF_INET6: - ip = "::" - # OS X can have some procs e.g. SystemUIServer listening on *:* - else: - raise ValueError("invalid IP %s" %addr) - if port == "*": - return 0 - return (ip, int(port)) - - diff --git a/third_party/psutil/psutil/_psutil_bsd.c b/third_party/psutil/psutil/_psutil_bsd.c deleted file mode 100644 index d937cbf..0000000 --- a/third_party/psutil/psutil/_psutil_bsd.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - * $Id: _psutil_bsd.c 1142 2011-10-05 18:45:49Z 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. - * - * FreeBSD platform-specific module methods for _psutil_bsd - */ - -#include <Python.h> -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/sysctl.h> -#include <sys/param.h> -#include <sys/user.h> -#include <sys/proc.h> -#include <sys/vmmeter.h> /* needed for vmtotal struct */ -#include <sys/mount.h> -// network-related stuff -#include <net/if.h> -#include <net/if_dl.h> -#include <net/route.h> - -#include "_psutil_bsd.h" -#include "_psutil_common.h" -#include "arch/bsd/process_info.h" - - -// convert a timeval struct to a double -#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) - - -/* - * Utility function which fills a kinfo_proc struct based on process pid - */ -static int -get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc) -{ - int mib[4]; - size_t size; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = pid; - - size = sizeof(struct kinfo_proc); - - 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. - */ - if (size == 0) { - NoSuchProcess(); - return -1; - } - return 0; -} - - -/* - * Return a Python list of all the PIDs running on the system. - */ -static PyObject* -get_pid_list(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; - - if (get_proc_list(&proclist, &num_processes) != 0) { - Py_DECREF(retlist); - PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list."); - return NULL; - } - - if (num_processes > 0) { - orig_address = proclist; // save so we can free it after we're done - for (idx=0; idx < num_processes; idx++) { - pid = Py_BuildValue("i", proclist->ki_pid); - PyList_Append(retlist, pid); - Py_XDECREF(pid); - proclist++; - } - free(orig_address); - } - - return retlist; -} - - -/* - * 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) -{ - /* 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); - return NULL; - } - boot_time = result.tv_sec; - return Py_BuildValue("f", (float)boot_time); -} - - -/* - * Return process name from kinfo_proc as a Python string. - */ -static PyObject* -get_process_name(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("s", kp.ki_comm); -} - - -/* - * Return process pathname executable. - * Thanks to Robert N. M. Watson: - * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_bin.c?v=8-CURRENT - */ -static PyObject* -get_process_exe(PyObject* self, PyObject* args) -{ - long pid; - char pathname[PATH_MAX]; - int error; - int mib[4]; - size_t size; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = pid; - - size = sizeof(pathname); - error = sysctl(mib, 4, pathname, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (size == 0 || strlen(pathname) == 0) { - if (pid_exists(pid) == 0) { - return NoSuchProcess(); - } - else { - strcpy(pathname, ""); - } - } - return Py_BuildValue("s", pathname); -} - - -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject* -get_process_cmdline(PyObject* self, PyObject* args) -{ - long pid; - PyObject* arglist = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - // get the commandline, defined in arch/bsd/process_info.c - arglist = get_arg_list(pid); - - // get_arg_list() returns NULL only if getcmdargs failed with ESRCH - // (no process with that PID) - if (NULL == arglist) { - return PyErr_SetFromErrno(PyExc_OSError); - } - return Py_BuildValue("N", arglist); -} - - -/* - * Return process parent pid from kinfo_proc as a Python integer. - */ -static PyObject* -get_process_ppid(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("l", (long)kp.ki_ppid); -} - - -/* - * Return process status as a Python integer. - */ -static PyObject* -get_process_status(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("i", (int)kp.ki_stat); -} - - -/* - * Return process real, effective and saved user ids from kinfo_proc - * as a Python tuple. - */ -static PyObject* -get_process_uids(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("lll", (long)kp.ki_ruid, - (long)kp.ki_uid, - (long)kp.ki_svuid); -} - - -/* - * Return process real, effective and saved group ids from kinfo_proc - * as a Python tuple. - */ -static PyObject* -get_process_gids(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_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 process real, effective and saved group ids from kinfo_proc - * as a Python tuple. - */ -static PyObject* -get_process_tty_nr(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("i", kp.ki_tdev); -} - - -/* - * Return number of threads used by process as a Python integer. - */ -static PyObject* -get_process_num_threads(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("l", (long)kp.ki_numthreads); -} - - -/* - * Retrieves all threads used by process returning a list of tuples - * including thread id, user time and system time. - * Thanks to Robert N. M. Watson: - * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_threads.c?v=8-CURRENT - */ -static PyObject* -get_process_threads(PyObject* self, PyObject* args) -{ - long pid; - int mib[4]; - struct kinfo_proc *kip; - struct kinfo_proc *kipp; - int error; - unsigned int i; - size_t size; - PyObject* retList = PyList_New(0); - PyObject* pyTuple = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - /* - * 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; - mib[3] = pid; - - size = 0; - error = sysctl(mib, 4, NULL, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (size == 0) { - return NoSuchProcess(); - } - - kip = malloc(size); - if (kip == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - error = sysctl(mib, 4, kip, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (size == 0) { - return NoSuchProcess(); - } - - 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) - ); - PyList_Append(retList, pyTuple); - Py_XDECREF(pyTuple); - } - free(kip); - return retList; -} - - -/* - * Return a Python tuple (user_time, kernel_time) - */ -static PyObject* -get_cpu_times(PyObject* self, PyObject* args) -{ - long pid; - double user_t, sys_t; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_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); - return Py_BuildValue("(dd)", user_t, sys_t); -} - - -/* - * Return a Python integer indicating the number of CPUs on the system - */ -static PyObject* -get_num_cpus(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; - } - - return Py_BuildValue("i", ncpu); -} - - -/* - * 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; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("d", TV2DOUBLE(kp.ki_start)); -} - - -/* - * 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) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - // there's apparently no way to determine bytes count, hence return -1. - return Py_BuildValue("(llll)", kp.ki_rusage.ru_inblock, - kp.ki_rusage.ru_oublock, - -1, -1); -} - - - -/* - * Return the RSS and VMS as a Python tuple. - */ -static PyObject* -get_memory_info(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("(ll)", ptoa(kp.ki_rssize), (long)kp.ki_size); -} - - -/* - * Return a Python integer indicating the total amount of physical memory - * in bytes. - */ -static PyObject* -get_total_phymem(PyObject* self, PyObject* args) -{ - long total_phymem; - int mib[2]; - size_t len; - - mib[0] = CTL_HW; - mib[1] = HW_PHYSMEM; - len = sizeof(total_phymem); - - if (sysctl(mib, 2, &total_phymem, &len, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - return Py_BuildValue("l", total_phymem); -} - - -/* - * Return a Python long indicating the amount of available physical memory in - * bytes. - */ -static PyObject* -get_avail_phymem(PyObject* self, PyObject* args) -{ - unsigned long v_inactive_count = 0; - unsigned long v_cache_count = 0; - unsigned long v_free_count = 0; - long total_mem = 0; - long long avail_mem = 0; - size_t size = sizeof(unsigned long); - size_t psize = sizeof(total_mem); - int pagesize = getpagesize(); - - if (sysctlbyname("hw.physmem", &total_mem, &psize, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - if (sysctlbyname("vm.stats.vm.v_inactive_count", &v_inactive_count, - &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - if (sysctlbyname("vm.stats.vm.v_cache_count", - &v_cache_count, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - if (sysctlbyname("vm.stats.vm.v_free_count", - &v_free_count, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - avail_mem = (v_inactive_count + v_cache_count + v_free_count) * pagesize; - // used_mem = total_mem - avail_mem; - - return Py_BuildValue("L", avail_mem); -} - - -/* - * Return a Python long indicating the total amount of virtual memory - * in bytes. - */ -static PyObject* -get_total_virtmem(PyObject* self, PyObject* args) -{ - int mib[2]; - struct vmtotal vm; - size_t size; - long long total_vmem; - - mib[0] = CTL_VM; - mib[1] = VM_METER; - size = sizeof(vm); - sysctl(mib, 2, &vm, &size, NULL, 0); - - // vmtotal struct: - // http://fxr.watson.org/fxr/source/sys/vmmeter.h?v=FREEBSD54 - // note: value is returned in page, so we must multiply by size of a page - total_vmem = (long long)vm.t_vm * (long long)getpagesize(); - return Py_BuildValue("L", total_vmem); -} - - -/* - * Return a Python long indicating the avail amount of virtual memory - * in bytes. - */ -static PyObject* -get_avail_virtmem(PyObject* self, PyObject* args) -{ - int mib[2]; - struct vmtotal vm; - size_t size; - long long total_vmem; - long long avail_vmem; - - mib[0] = CTL_VM; - mib[1] = VM_METER; - size = sizeof(vm); - sysctl(mib, 2, &vm, &size, NULL, 0); - - // vmtotal struct: - // http://fxr.watson.org/fxr/source/sys/vmmeter.h?v=FREEBSD54 - // note: value is returned in page, so we must multiply by size of a page - total_vmem = (long long)vm.t_vm * (long long)getpagesize(); - avail_vmem = total_vmem - ((long long)vm.t_avm * (long long)getpagesize()); - return Py_BuildValue("L", avail_vmem); -} - - -/* - * Return a Python tuple representing user, kernel and idle CPU times - */ -static PyObject* -get_system_cpu_times(PyObject* self, PyObject* args) -{ - long cpu_time[CPUSTATES]; - size_t size; - - size = sizeof(cpu_time); - - if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - return Py_BuildValue("(ddddd)", - (double)cpu_time[CP_USER] / CLOCKS_PER_SEC, - (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC, - (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC, - (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC, - (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC - ); -} - - -/* - * Return a Python list of tuple representing per-cpu times - */ -static PyObject* -get_system_per_cpu_times(PyObject* self, PyObject* args) -{ - static int maxcpus; - int mib[2]; - int ncpu; - size_t len; - size_t size; - int i; - PyObject* py_retlist = PyList_New(0); - PyObject* py_cputime; - - // retrieve maxcpus value - size = sizeof(maxcpus); - if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) { - PyErr_SetFromErrno(0); - return NULL; - } - long cpu_time[maxcpus][CPUSTATES]; - - // retrieve the number of cpus - 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; - } - - // per-cpu info - size = sizeof(cpu_time); - if (sysctlbyname("kern.cp_times", &cpu_time, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - 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 - ); - PyList_Append(py_retlist, py_cputime); - Py_XDECREF(py_cputime); - } - - return py_retlist; -} - - -/* - * 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) -{ - int num; - int i; - long len; - struct statfs *fs; - PyObject* py_retlist = PyList_New(0); - PyObject* py_tuple; - - // get the number of mount points - Py_BEGIN_ALLOW_THREADS - num = getfsstat(NULL, 0, MNT_NOWAIT); - Py_END_ALLOW_THREADS - if (num == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - len = sizeof(*fs) * num; - fs = malloc(len); - - Py_BEGIN_ALLOW_THREADS - num = getfsstat(fs, len, MNT_NOWAIT); - Py_END_ALLOW_THREADS - if (num == -1) { - free(fs); - PyErr_SetFromErrno(0); - return NULL; - } - - for (i = 0; i < num; i++) { - py_tuple = Py_BuildValue("(sss)", fs[i].f_mntfromname, // device - fs[i].f_mntonname, // mount point - fs[i].f_fstypename); // fs type - PyList_Append(py_retlist, py_tuple); - Py_XDECREF(py_tuple); - } - - free(fs); - return py_retlist; -} - - -/* - * Return a Python list of named tuples with overall network I/O information - */ -static PyObject* -get_network_io_counters(PyObject* self, PyObject* args) -{ - PyObject* py_retdict = PyDict_New(); - PyObject* py_ifc_info; - - char *buf = NULL, *lim, *next; - struct if_msghdr *ifm; - int mib[6]; - size_t len; - - mib[0] = CTL_NET; // networking subsystem - mib[1] = PF_ROUTE; // type of information - mib[2] = 0; // protocol (IPPROTO_xxx) - mib[3] = 0; // address family - mib[4] = NET_RT_IFLIST; // operation - mib[5] = 0; - - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { - Py_DECREF(py_retdict); - PyErr_SetFromErrno(0); - return NULL; - } - - - buf = malloc(len); - - if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { - if (buf) { - free(buf); - } - Py_DECREF(py_retdict); - PyErr_SetFromErrno(0); - return NULL; - } - - lim = buf + len; - - for (next = buf; next < lim; ) { - ifm = (struct if_msghdr *)next; - next += ifm->ifm_msglen; - - if (ifm->ifm_type == RTM_IFINFO) { - struct if_msghdr *if2m = (struct if_msghdr *)ifm; - struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1); - char ifc_name[32]; - - strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen); - ifc_name[sdl->sdl_nlen] = 0; - - py_ifc_info = Py_BuildValue("(KKKK)", - if2m->ifm_data.ifi_obytes, - if2m->ifm_data.ifi_ibytes, - if2m->ifm_data.ifi_opackets, - if2m->ifm_data.ifi_ipackets); - PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info); - Py_XDECREF(py_ifc_info); - } - else { - continue; - } - } - - return py_retdict; -} - - - - -/* - * define the psutil C module methods and initialize the module. - */ -static PyMethodDef -PsutilMethods[] = -{ - // --- per-process functions - - {"get_process_name", get_process_name, METH_VARARGS, - "Return process name"}, - {"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_cpu_times", get_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_memory_info", get_memory_info, METH_VARARGS, - "Return a tuple of RSS/VMS memory information"}, - {"get_process_num_threads", get_process_num_threads, METH_VARARGS, - "Return number of threads used 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"}, - - - // --- 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_total_phymem", get_total_phymem, METH_VARARGS, - "Return the total amount of physical memory, in bytes"}, - {"get_avail_phymem", get_avail_phymem, METH_VARARGS, - "Return the amount of available physical memory, in bytes"}, - {"get_total_virtmem", get_total_virtmem, METH_VARARGS, - "Return the total amount of virtual memory, in bytes"}, - {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS, - "Return the amount of available virtual 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 a float indicating 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."}, - - {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_bsd_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int -psutil_bsd_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - return 0; -} - -static struct PyModuleDef -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) - -#else -#define INITERROR return - -void init_psutil_bsd(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods); -#endif - PyModule_AddIntConstant(module, "SSTOP", SSTOP); - PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); - PyModule_AddIntConstant(module, "SRUN", SRUN); - PyModule_AddIntConstant(module, "SIDL", SIDL); - PyModule_AddIntConstant(module, "SWAIT", SWAIT); - PyModule_AddIntConstant(module, "SLOCK", SLOCK); - PyModule_AddIntConstant(module, "SZOMB", SZOMB); - - if (module == NULL) { - INITERROR; - } -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} - diff --git a/third_party/psutil/psutil/_psutil_bsd.h b/third_party/psutil/psutil/_psutil_bsd.h deleted file mode 100644 index 2cc76ae..0000000 --- a/third_party/psutil/psutil/_psutil_bsd.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * $Id: _psutil_bsd.h 1142 2011-10-05 18:45:49Z 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. - * - * BSD platform-specific module methods for _psutil_bsd - */ - -#include <Python.h> - -// --- per-process functions - -static PyObject* get_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_create_time(PyObject* self, PyObject* args); -static PyObject* get_memory_info(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_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); - -// --- system-related functions - -static PyObject* get_pid_list(PyObject* self, PyObject* args); -static PyObject* get_num_cpus(PyObject* self, PyObject* args); -static PyObject* get_total_phymem(PyObject* self, PyObject* args); -static PyObject* get_avail_phymem(PyObject* self, PyObject* args); -static PyObject* get_total_virtmem(PyObject* self, PyObject* args); -static PyObject* get_avail_virtmem(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); diff --git a/third_party/psutil/psutil/_psutil_common.c b/third_party/psutil/psutil/_psutil_common.c deleted file mode 100644 index 79aef97..0000000 --- a/third_party/psutil/psutil/_psutil_common.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * $Id: _psutil_common.c 1142 2011-10-05 18:45:49Z 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. - * - * Routines common to all platforms. - */ - -#include <Python.h> - - -/* - * Set OSError(errno=ESRCH, strerror="No such process") Python exception. - */ -PyObject * -NoSuchProcess(void) { - PyObject *exc; - char *msg = strerror(ESRCH); - exc = PyObject_CallFunction(PyExc_OSError, "(is)", ESRCH, msg); - PyErr_SetObject(PyExc_OSError, exc); - Py_XDECREF(exc); - return NULL; -} - -/* - * Set OSError(errno=EACCES, strerror="Permission denied") Python exception. - */ -PyObject * -AccessDenied(void) { - PyObject *exc; - char *msg = strerror(EACCES); - exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg); - PyErr_SetObject(PyExc_OSError, exc); - Py_XDECREF(exc); - return NULL; -} - diff --git a/third_party/psutil/psutil/_psutil_common.h b/third_party/psutil/psutil/_psutil_common.h deleted file mode 100644 index cfe9493..0000000 --- a/third_party/psutil/psutil/_psutil_common.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * $Id: _psutil_common.h 1142 2011-10-05 18:45:49Z 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> - -PyObject* NoSuchProcess(void); -PyObject* AccessDenied(void); - diff --git a/third_party/psutil/psutil/_psutil_linux.c b/third_party/psutil/psutil/_psutil_linux.c deleted file mode 100644 index 6915c0c..0000000 --- a/third_party/psutil/psutil/_psutil_linux.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * $Id: _psutil_linux.c 1142 2011-10-05 18:45:49Z 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. - * - * Linux-specific functions. - */ - -#include <Python.h> -#include <errno.h> -#include <stdlib.h> -#include <mntent.h> -#include <sys/syscall.h> -#include <linux/unistd.h> - -#include "_psutil_linux.h" - - -#define HAS_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set) - -#if HAS_IOPRIO -enum { - IOPRIO_WHO_PROCESS = 1, -}; - -static inline int -ioprio_get(int which, int who) -{ - return syscall(__NR_ioprio_get, which, who); -} - -static inline int -ioprio_set(int which, int who, int ioprio) -{ - return syscall(__NR_ioprio_set, which, who, ioprio); -} - -#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) - - -/* - * Return a (ioclass, iodata) Python tuple representing process I/O priority. - */ -static PyObject* -linux_ioprio_get(PyObject* self, PyObject* args) -{ - long pid; - int ioprio, ioclass, iodata; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); - if (ioprio == -1) { - return PyErr_SetFromErrno(PyExc_OSError); - } - ioclass = IOPRIO_PRIO_CLASS(ioprio); - iodata = IOPRIO_PRIO_DATA(ioprio); - return Py_BuildValue("ii", ioclass, iodata); -} - - -/* - * A wrapper around ioprio_set(); sets process I/O priority. - * 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) -{ - long pid; - int ioprio, ioclass, iodata; - int retval; - - 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) { - return PyErr_SetFromErrno(PyExc_OSError); - } - Py_INCREF(Py_None); - return Py_None; -} -#endif - - -/* - * 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) -{ - FILE *file; - struct mntent *entry; - PyObject* py_retlist = PyList_New(0); - PyObject* py_tuple; - - // MOUNTED constant comes from mntent.h and it's == '/etc/mtab' - Py_BEGIN_ALLOW_THREADS - file = setmntent(MOUNTED, "r"); - Py_END_ALLOW_THREADS - if ((file == 0) || (file == NULL)) { - return PyErr_SetFromErrno(PyExc_OSError); - } - - while ((entry = getmntent(file))) { - if (entry == NULL) { - endmntent(file); - return PyErr_Format(PyExc_RuntimeError, "getmntent() failed"); - } - py_tuple = Py_BuildValue("(sss)", entry->mnt_fsname, // device - entry->mnt_dir, // mount point - entry->mnt_type); // fs type - PyList_Append(py_retlist, py_tuple); - Py_XDECREF(py_tuple); - } - - endmntent(file); - return py_retlist; -} - - -/* - * 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"}, - - {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_linux_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int -psutil_linux_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - return 0; -} - -static struct PyModuleDef -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) - -#else -#define INITERROR return - -void init_psutil_linux(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods); -#endif - if (module == NULL) { - INITERROR; - } -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} - diff --git a/third_party/psutil/psutil/_psutil_linux.h b/third_party/psutil/psutil/_psutil_linux.h deleted file mode 100644 index 1dc36c8..0000000 --- a/third_party/psutil/psutil/_psutil_linux.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * $Id: _psutil_linux.h 1142 2011-10-05 18:45:49Z 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. - * - * 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); - diff --git a/third_party/psutil/psutil/_psutil_mswindows.c b/third_party/psutil/psutil/_psutil_mswindows.c deleted file mode 100644 index 3964179..0000000 --- a/third_party/psutil/psutil/_psutil_mswindows.c +++ /dev/null @@ -1,1897 +0,0 @@ -/* - * $Id: _psutil_mswindows.c 1142 2011-10-05 18:45:49Z 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. - * - * Windows platform-specific module methods for _psutil_mswindows - */ - -#include <Python.h> -#include <windows.h> -#include <Psapi.h> -#include <time.h> -#include <lm.h> -#include <tchar.h> -#include <tlhelp32.h> -#include <iphlpapi.h> - -#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_uptime(PyObject* self, PyObject* args) -{ - double uptime; - time_t pt; - FILETIME fileTime; - long long ll; - - GetSystemTimeAsFileTime(&fileTime); - - /* - HUGE thanks to: - http://johnstewien.spaces.live.com/blog/cns!E6885DB5CEBABBC8!831.entry - - This function converts the FILETIME structure to the 32 bit - Unix time structure. - The time_t is a 32-bit value for the number of seconds since - January 1, 1970. A FILETIME is a 64-bit for the number of - 100-nanosecond periods since January 1, 1601. Convert by - subtracting the number of 100-nanosecond period betwee 01-01-1970 - and 01-01-1601, from time_t the divide by 1e+7 to get to the same - base granularity. - */ - ll = (((LONGLONG)(fileTime.dwHighDateTime)) << 32) + fileTime.dwLowDateTime; - pt = (time_t)((ll - 116444736000000000ull) / 10000000ull); - - // XXX - By using GetTickCount() time will wrap around to zero if the - // system is run continuously for 49.7 days. - uptime = GetTickCount() / 1000.00f; - return Py_BuildValue("d", (double)pt - uptime); -} - - -/* - * Return 1 if PID exists in the current process list, else 0. - */ -static PyObject* -pid_exists(PyObject* self, PyObject* args) -{ - long pid; - int status; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - status = pid_is_running(pid); - if (-1 == status) { - return NULL; // exception raised in 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); - - proclist = get_pids(&numberOfReturnedPIDs); - if (NULL == proclist) { - Py_DECREF(retlist); - return NULL; - } - - for (i = 0; i < numberOfReturnedPIDs; i++) { - pid = Py_BuildValue("I", proclist[i]); - PyList_Append(retlist, pid); - Py_XDECREF(pid); - } - - // free C array allocated for PIDs - free(proclist); - - return retlist; -} - - -/* - * Kill a process given its PID. - */ -static PyObject* -kill_process(PyObject* self, PyObject* args) -{ - HANDLE hProcess; - long pid; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (pid == 0) { - return AccessDenied(); - } - - hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid); - if (hProcess == NULL) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - // see http://code.google.com/p/psutil/issues/detail?id=24 - NoSuchProcess(); - } - else { - PyErr_SetFromWindowsErr(0); - } - return NULL; - } - - // kill the process - if (! TerminateProcess(hProcess, 0)) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hProcess); - return NULL; - } - - CloseHandle(hProcess); - Py_INCREF(Py_None); - return Py_None; -} - - -/* - * Wait for process to terminate and return its exit code. - */ -static PyObject* -process_wait(PyObject* self, PyObject* args) -{ - HANDLE hProcess; - DWORD ExitCode; - DWORD retVal; - long pid; - long timeout; - - if (! PyArg_ParseTuple(args, "ll", &pid, &timeout)) { - return NULL; - } - if (pid == 0) { - return AccessDenied(); - } - - hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid); - if (hProcess == NULL) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - // no such process; we do not want to raise NSP but - // return None instead. - Py_INCREF(Py_None); - return Py_None; - } - else { - PyErr_SetFromWindowsErr(0); - return NULL; - } - } - - // wait until the process has terminated - Py_BEGIN_ALLOW_THREADS - retVal = WaitForSingleObject(hProcess, timeout); - Py_END_ALLOW_THREADS - - if (retVal == WAIT_FAILED) { - CloseHandle(hProcess); - return PyErr_SetFromWindowsErr(GetLastError()); - } - if (retVal == WAIT_TIMEOUT) { - CloseHandle(hProcess); - return Py_BuildValue("l", WAIT_TIMEOUT); - } - - // get the exit code; note: subprocess module (erroneously?) uses - // what returned by WaitForSingleObject - if (GetExitCodeProcess(hProcess, &ExitCode) == 0) { - CloseHandle(hProcess); - return PyErr_SetFromWindowsErr(GetLastError()); - } - CloseHandle(hProcess); -#if PY_MAJOR_VERSION >= 3 - return PyLong_FromLong((long) ExitCode); -#else - return PyInt_FromLong((long) ExitCode); -#endif -} - - -/* - * Return a Python tuple (user_time, kernel_time) - */ -static PyObject* -get_process_cpu_times(PyObject* self, PyObject* args) -{ - long pid; - HANDLE hProcess; - FILETIME ftCreate, ftExit, ftKernel, ftUser; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - // special case for PID 0 - if (0 == pid){ - return Py_BuildValue("(dd)", 0.0, 0.0); - } - - hProcess = 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* -get_process_create_time(PyObject* self, PyObject* args) -{ - long pid; - long long unix_time; - HANDLE hProcess; - FILETIME ftCreate, ftExit, ftKernel, ftUser; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - // special case for PIDs 0 and 4 - if ( (0 == pid) || (4 == pid) ){ - return Py_BuildValue("d", 0.0); - } - - hProcess = 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); - - /* - 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 a Python integer indicating the number of CPUs on the system. - */ -static PyObject* -get_num_cpus(PyObject* self, PyObject* args) -{ - SYSTEM_INFO system_info; - system_info.dwNumberOfProcessors = 0; - - GetSystemInfo(&system_info); - if (system_info.dwNumberOfProcessors == 0){ - // GetSystemInfo failed for some reason; return 1 as default - return Py_BuildValue("I", 1); - } - return Py_BuildValue("I", system_info.dwNumberOfProcessors); -} - -/* - * Return process name as a Python string. - */ -static PyObject* -get_process_name(PyObject* self, PyObject* args) { - long pid; - int pid_return; - PyObject* name; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - if (pid == 0) { - return Py_BuildValue("s", "System Idle Process"); - } - else if (pid == 4) { - return Py_BuildValue("s", "System"); - } - - pid_return = pid_is_running(pid); - if (pid_return == 0) { - return NoSuchProcess(); - } - if (pid_return == -1) { - return NULL; - } - - name = get_name(pid); - if (name == NULL) { - return NULL; // exception set in 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 = pid_is_running(pid); - if (pid_return == 0) { - return NoSuchProcess(); - } - if (pid_return == -1) { - return NULL; - } - - ppid = get_ppid(pid); - if (ppid == NULL) { - return NULL; // exception set in 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 = pid_is_running(pid); - if (pid_return == 0) { - return NoSuchProcess(); - } - if (pid_return == -1) { - return NULL; - } - - // 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 = get_arg_list(pid); - if ( NULL == arglist ) { - // carry on anyway, clear any exceptions too - PyErr_Clear(); - return Py_BuildValue("[]"); - } - - return arglist; -} - - -/* - * Return the RSS and VMS as a Python tuple. - */ -static PyObject* -get_memory_info(PyObject* self, PyObject* args) -{ - HANDLE hProcess; - PROCESS_MEMORY_COUNTERS counters; - DWORD pid; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - hProcess = handle_from_pid(pid); - if (NULL == hProcess) { - return NULL; - } - - if (! GetProcessMemoryInfo(hProcess, &counters, sizeof(counters)) ) { - CloseHandle(hProcess); - return PyErr_SetFromWindowsErr(0); - } - - CloseHandle(hProcess); - return Py_BuildValue("(nn)", counters.WorkingSetSize, counters.PagefileUsage); -} - - -/* - * Return a Python integer indicating the total amount of physical memory - * in bytes. - */ -static PyObject* -get_system_phymem(PyObject* self, PyObject* args) -{ - MEMORYSTATUSEX memInfo; - memInfo.dwLength = sizeof(MEMORYSTATUSEX); - - if (! GlobalMemoryStatusEx(&memInfo) ) { - return PyErr_SetFromWindowsErr(0); - } - - return Py_BuildValue("(LLLLLLk)", - memInfo.ullTotalPhys, // total - memInfo.ullAvailPhys, // avail - memInfo.ullTotalPageFile, // total page file - memInfo.ullAvailPageFile, // avail page file - memInfo.ullTotalVirtual, // total virtual - memInfo.ullAvailVirtual, // avail virtual - memInfo.dwMemoryLoad // percent - ); -} - - -#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); - - // 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++) { - 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); - PyList_Append(retlist, arg); - Py_XDECREF(arg); - } - free(sppi); - FreeLibrary(hNtDll); - return retlist; - - } // END NtQuerySystemInformation - } // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION - } // END GetProcAddress - } // END LoadLibrary - - 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; - PVOID pebAddress; - PVOID rtlUserProcParamsAddress; - UNICODE_STRING currentDirectory; - WCHAR *currentDirectoryContent; - PyObject *returnPyObj = NULL; - PyObject *cwd_from_wchar = NULL; - PyObject *cwd = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - processHandle = handle_from_pid(pid); - if (processHandle == NULL) { - return NULL; - } - - pebAddress = GetPebAddress(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) { - /* Usually means the process has gone in the meantime */ - return NoSuchProcess(); - } - else { - return PyErr_SetFromWindowsErr(0); - } - - } - - /* read the currentDirectory UNICODE_STRING structure. - 0x24 refers to "CurrentDirectoryPath" of RTL_USER_PROCESS_PARAMETERS - structure (http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/) - */ -#ifdef _WIN64 - if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 56, - ¤tDirectory, sizeof(currentDirectory), NULL)) -#else - if (!ReadProcessMemory(processHandle, (PCHAR)rtlUserProcParamsAddress + 0x24, - ¤tDirectory, sizeof(currentDirectory), NULL)) -#endif - { - CloseHandle(processHandle); - if (GetLastError() == ERROR_PARTIAL_COPY) { - /* Usually means the process has gone in the meantime */ - return NoSuchProcess(); - } - else { - return PyErr_SetFromWindowsErr(0); - } - } - - /* allocate memory to hold the command line */ - currentDirectoryContent = (WCHAR *)malloc(currentDirectory.Length+1); - - /* read the command line */ - if (!ReadProcessMemory(processHandle, currentDirectory.Buffer, - currentDirectoryContent, currentDirectory.Length, NULL)) - { - CloseHandle(processHandle); - free(currentDirectoryContent); - - if (GetLastError() == ERROR_PARTIAL_COPY) { - /* Usually means the process has gone in the meantime */ - return NoSuchProcess(); - } - else { - return PyErr_SetFromWindowsErr(0); - } - } - - // null-terminate the string to prevent wcslen from returning incorrect length - // the length specifier is in characters, but commandLine.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 PY_MAJOR_VERSION >= 3 - cwd = PyUnicode_FromObject(cwd_from_wchar); - #else - cwd = PyUnicode_AsUTF8String(cwd_from_wchar); - #endif - - // decrement the reference count on our temp unicode str to avoid mem leak - Py_XDECREF(cwd_from_wchar); - returnPyObj = Py_BuildValue("N", cwd); - - CloseHandle(processHandle); - free(currentDirectoryContent); - return returnPyObj; -} - - -/* - * Resume or suspends a process - */ -int -suspend_resume_process(DWORD pid, int suspend) -{ - // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx - HANDLE hThreadSnap = NULL; - THREADENTRY32 te32 = {0}; - - if (pid == 0) { - AccessDenied(); - return FALSE; - } - - hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (hThreadSnap == INVALID_HANDLE_VALUE) { - PyErr_SetFromWindowsErr(0); - return FALSE; - } - - // Fill in the size of the structure before using it - te32.dwSize = sizeof(THREADENTRY32); - - if (! Thread32First(hThreadSnap, &te32)) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hThreadSnap); - return FALSE; - } - - // Walk the thread snapshot to find all threads of the process. - // If the thread belongs to the process, add its information - // to the display list. - do - { - if (te32.th32OwnerProcessID == pid) - { - HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, - te32.th32ThreadID); - if (hThread == NULL) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hThread); - CloseHandle(hThreadSnap); - return FALSE; - } - if (suspend == 1) - { - if (SuspendThread(hThread) == (DWORD)-1) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hThread); - CloseHandle(hThreadSnap); - return FALSE; - } - } - else - { - if (ResumeThread(hThread) == (DWORD)-1) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hThread); - CloseHandle(hThreadSnap); - return FALSE; - } - } - CloseHandle(hThread); - } - } while (Thread32Next(hThreadSnap, &te32)); - - 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) != 1) { - free(buffer); - return NULL; - } - if (pid_is_running(pid) == 0) { - free(buffer); - return NoSuchProcess(); - } - - num = (int)process->NumberOfThreads; - free(buffer); - return Py_BuildValue("i", num); -} - - -static PyObject* -get_process_threads(PyObject* self, PyObject* args) -{ - PyObject* retList = PyList_New(0); - PyObject* pyTuple = NULL; - HANDLE hThreadSnap = NULL; - THREADENTRY32 te32 = {0}; - long pid; - int pid_return; - int rc; - FILETIME ftDummy, ftKernel, ftUser; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (pid == 0) { - // raise AD instead of returning 0 as procexp is able to - // retrieve useful information somehow - return AccessDenied(); - } - - pid_return = pid_is_running(pid); - if (pid_return == 0) { - return NoSuchProcess(); - } - if (pid_return == -1) { - return NULL; - } - - hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (hThreadSnap == INVALID_HANDLE_VALUE) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - - // Fill in the size of the structure before using it - te32.dwSize = sizeof(THREADENTRY32); - - if (! Thread32First(hThreadSnap, &te32)) { - PyErr_SetFromWindowsErr(0); - CloseHandle(hThreadSnap); - return NULL; - } - - // 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) - { - HANDLE 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); - CloseHandle(hThread); - CloseHandle(hThreadSnap); - return NULL; - } - - /* - user and kernel times are represented as a FILETIME structure - wich contains a 64-bit value representing the number of - 100-nanosecond intervals since January 1, 1601 (UTC). - http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx - - To convert it into a float representing the seconds that the - process has executed in user/kernel mode I borrowed the code - below from Python's Modules/posixmodule.c - */ - pyTuple = Py_BuildValue("kdd", - te32.th32ThreadID, - (double)(ftUser.dwHighDateTime*429.4967296 + \ - ftUser.dwLowDateTime*1e-7), - (double)(ftKernel.dwHighDateTime*429.4967296 + \ - ftKernel.dwLowDateTime*1e-7) - ); - PyList_Append(retList, pyTuple); - Py_XDECREF(pyTuple); - - CloseHandle(hThread); - } - } while (Thread32Next(hThreadSnap, &te32)); - - CloseHandle(hThreadSnap); - return retList; -} - - - -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 = handle_from_pid_waccess(pid, access); - if (processHandle == NULL) { - return NULL; - } - - filesList = 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 = 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 (!GetTokenInformation(tokenHandle, - TokenUser, - user, - bufferSize, - &bufferSize)) - { - free(user); - user = malloc(bufferSize); - - 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)); - domainName = malloc(domainNameSize * sizeof(TCHAR)); - - if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName, - &domainNameSize, &nameUse)) - { - free(name); - free(domainName); - name = malloc(nameSize * sizeof(TCHAR)); - domainName = malloc(domainNameSize * sizeof(TCHAR)); - - 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)); - 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; - - -/* - * 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; - 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; - 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; - CHAR addressBufferRemote[65]; - PyObject* addressTupleRemote; - - if (!PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - if (pid_is_running(pid) == 0) { - 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"); - } - - if ((getExtendedTcpTable == NULL) || (getExtendedUdpTable == NULL)) { - PyErr_SetString(PyExc_NotImplementedError, - "feature not supported on this Windows version"); - return NULL; - } - - connectionsList = PyList_New(0); - - /* TCP IPv4 */ - - tableSize = 0; - getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET, - TCP_TABLE_OWNER_PID_ALL, 0); - - table = malloc(tableSize); - - 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); - } - - // 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); - } - - connectionTuple = Py_BuildValue("(iiiNNs)", - -1, - AF_INET, - SOCK_STREAM, - addressTupleLocal, - addressTupleRemote, - state_to_string(tcp4Table->table[i].dwState) - ); - PyList_Append(connectionsList, connectionTuple); - } - } - - free(table); - - /* TCP IPv6 */ - - tableSize = 0; - getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6, - TCP_TABLE_OWNER_PID_ALL, 0); - - table = malloc(tableSize); - - 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); - } - - // 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); - } - - connectionTuple = Py_BuildValue("(iiiNNs)", - -1, - AF_INET6, - SOCK_STREAM, - addressTupleLocal, - addressTupleRemote, - state_to_string(tcp6Table->table[i].dwState) - ); - PyList_Append(connectionsList, connectionTuple); - } - } - - free(table); - - /* UDP IPv4 */ - - tableSize = 0; - getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET, - UDP_TABLE_OWNER_PID, 0); - - table = malloc(tableSize); - - 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); - } - - connectionTuple = Py_BuildValue("(iiiNNs)", - -1, - AF_INET, - SOCK_DGRAM, - addressTupleLocal, - PyTuple_New(0), - "" - ); - PyList_Append(connectionsList, connectionTuple); - } - } - - free(table); - - /* UDP IPv6 */ - - tableSize = 0; - getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET6, UDP_TABLE_OWNER_PID, 0); - - table = malloc(tableSize); - - 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); - } - - connectionTuple = Py_BuildValue("(iiiNNs)", - -1, - AF_INET6, - SOCK_DGRAM, - addressTupleLocal, - PyTuple_New(0), - "" - ); - PyList_Append(connectionsList, connectionTuple); - } - } - - free(table); - - return connectionsList; -} - - -/* - * 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 = 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 = 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; -} - - -/* - * 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; - } - if (pid == 0) { - return AccessDenied(); - } - hProcess = handle_from_pid(pid); - if (NULL == hProcess) { - return NULL; - } - if (! GetProcessIoCounters(hProcess, &IoCounters)) { - CloseHandle(hProcess); - return PyErr_SetFromWindowsErr(0); - } - CloseHandle(hProcess); - return Py_BuildValue("(KKKK)", IoCounters.ReadOperationCount, - IoCounters.WriteOperationCount, - IoCounters.ReadTransferCount, - IoCounters.WriteTransferCount); -} - - -/* - * Return 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) != 1) { - free(buffer); - return NULL; - } - if (pid_is_running(pid) == 0) { - free(buffer); - return NoSuchProcess(); - } - - 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 disk partitions as a list of namedtuples. - */ -static PyObject* -win32_GetLogicalDriveStrings(PyObject* self, PyObject* args) -{ - DWORD num_bytes; - char drive_strings[255]; - char* drive_letter = drive_strings; - PyObject* py_retlist = PyList_New(0); - - Py_BEGIN_ALLOW_THREADS - num_bytes = GetLogicalDriveStrings(254, drive_letter); - Py_END_ALLOW_THREADS - - if (num_bytes == 0) { - return PyErr_SetFromWindowsErr(0); - } - - while (*drive_letter != 0) { - PyList_Append(py_retlist, Py_BuildValue("s", drive_letter)); - drive_letter = strchr(drive_letter, 0) +1; - } - - return py_retlist; -} - - -static PyObject* -win32_GetDriveType(PyObject* self, PyObject* args) -{ - LPCTSTR drive_letter; - int type; - char* type_str; - - if (! PyArg_ParseTuple(args, "s", &drive_letter)) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - type = GetDriveType(drive_letter); - Py_END_ALLOW_THREADS - - switch (type) { - case DRIVE_UNKNOWN: - type_str = "unknown"; - break; - case DRIVE_NO_ROOT_DIR: - type_str = "unmounted"; - case DRIVE_REMOVABLE: - type_str = "removable"; - break; - case DRIVE_FIXED: - type_str = "fixed"; - break; - case DRIVE_REMOTE: - type_str = "remote"; - break; - case DRIVE_CDROM: - type_str = "cdrom"; - break; - case DRIVE_RAMDISK: - type_str = "ramdisk"; - break; - default: - type_str = "?"; - break; - } - - return Py_BuildValue("s", type_str); -} - - -// ------------------------ 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_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_memory_info", get_memory_info, METH_VARARGS, - "Return a tuple of RSS/VMS 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."}, - {"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"}, - - // --- 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_uptime", get_system_uptime, METH_VARARGS, - "Return system uptime"}, - {"get_system_phymem", get_system_phymem, 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."}, - - // --- windows API bindings - {"win32_GetLogicalDriveStrings", win32_GetLogicalDriveStrings, METH_VARARGS, - "GetLogicalDriveStrings binding"}, - {"win32_GetDriveType", win32_GetDriveType, METH_VARARGS, - "GetDriveType binding"}, - {"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); - SetSeDebug(); - -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} - - - diff --git a/third_party/psutil/psutil/_psutil_mswindows.h b/third_party/psutil/psutil/_psutil_mswindows.h deleted file mode 100644 index c4ff4bc..0000000 --- a/third_party/psutil/psutil/_psutil_mswindows.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * $Id: _psutil_mswindows.h 1142 2011-10-05 18:45:49Z 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. - * - * Windows platform-specific module methods for _psutil_mswindows - */ - -#include <Python.h> -#include <windows.h> - -// --- per-process functions - -static PyObject* kill_process(PyObject* self, PyObject* args); -static PyObject* get_process_name(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_cpu_times(PyObject* self, PyObject* args); -static PyObject* get_process_create_time(PyObject* self, PyObject* args); -static PyObject* get_memory_info(PyObject* self, PyObject* args); -static PyObject* get_process_cwd(PyObject* self, PyObject* args); -static PyObject* suspend_process(PyObject* self, PyObject* args); -static PyObject* resume_process(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* process_wait(PyObject* self, PyObject* args); -static PyObject* get_process_priority(PyObject* self, PyObject* args); -static PyObject* set_process_priority(PyObject* self, PyObject* args); -static PyObject* get_process_io_counters(PyObject* self, PyObject* args); -static PyObject* is_process_suspended(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_uptime(PyObject* self, PyObject* args); -static PyObject* get_system_phymem(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); - -// --- windows API bindings - -static PyObject* win32_QueryDosDevice(PyObject* self, PyObject* args); -static PyObject* win32_GetLogicalDriveStrings(PyObject* self, PyObject* args); -static PyObject* win32_GetDriveType(PyObject* self, PyObject* args); - -// --- internal -int suspend_resume_process(DWORD pid, int suspend); diff --git a/third_party/psutil/psutil/_psutil_osx.c b/third_party/psutil/psutil/_psutil_osx.c deleted file mode 100644 index 29162f2..0000000 --- a/third_party/psutil/psutil/_psutil_osx.c +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * $Id: _psutil_osx.c 1142 2011-10-05 18:45:49Z 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. - * - * OS X platform-specific module methods for _psutil_osx - */ - -#include <Python.h> -#include <assert.h> -#include <errno.h> -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/sysctl.h> -#include <sys/vmmeter.h> -#include <libproc.h> -#include <sys/proc_info.h> -#include <netinet/tcp_fsm.h> -#include <arpa/inet.h> -#include <net/if_dl.h> - -#include <mach/mach.h> -#include <mach/task.h> -#include <mach/mach_init.h> -#include <mach/host_info.h> -#include <mach/mach_host.h> -#include <mach/mach_traps.h> -#include <mach/shared_memory_server.h> - -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/storage/IOBlockStorageDriver.h> -#include <IOKit/storage/IOMedia.h> -#include <IOKit/IOBSD.h> - -#include "_psutil_osx.h" -#include "_psutil_common.h" -#include "arch/osx/process_info.h" - - -/* - * Return a Python list of all the PIDs running on the system. - */ -static PyObject* -get_pid_list(PyObject* self, PyObject* args) -{ - kinfo_proc *proclist = NULL; - kinfo_proc *orig_address = NULL; - size_t num_processes; - size_t idx; - PyObject *pid; - PyObject *retlist = PyList_New(0); - - if (get_proc_list(&proclist, &num_processes) != 0) { - Py_DECREF(retlist); - PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list."); - return NULL; - } - - 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++) { - pid = Py_BuildValue("i", proclist->kp_proc.p_pid); - PyList_Append(retlist, pid); - Py_XDECREF(pid); - proclist++; - } - } - free(orig_address); - return retlist; -} - - -/* - * Return process name from kinfo_proc as a Python string. - */ -static PyObject* -get_process_name(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("s", kp.kp_proc.p_comm); -} - - -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject* -get_process_cmdline(PyObject* self, PyObject* args) -{ - long pid; - PyObject* arglist = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - // get the commandline, defined in arch/osx/process_info.c - arglist = get_arg_list(pid); - return arglist; -} - - -/* - * Return process parent pid from kinfo_proc as a Python integer. - */ -static PyObject* -get_process_ppid(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid); -} - - -/* - * Return process real uid from kinfo_proc as a Python integer. - */ -static PyObject* -get_process_uids(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (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 process real group id from ki_comm as a Python integer. - */ -static PyObject* -get_process_gids(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (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 process controlling terminal number as an integer. - */ -static PyObject* -get_process_tty_nr(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("i", kp.kp_eproc.e_tdev); -} - - -/* - * Return a Python integer indicating the number of CPUs on the system. - */ -static PyObject* -get_num_cpus(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; - } - - return Py_BuildValue("i", ncpu); -} - - -#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) - -/* - * Return a Python tuple (user_time, kernel_time) - */ -static PyObject* -get_cpu_times(PyObject* self, PyObject* args) -{ - long pid; - int err; - unsigned int info_count = TASK_BASIC_INFO_COUNT; - task_port_t task; // = (task_port_t)NULL; - time_value_t user_time, system_time; - struct task_basic_info tasks_info; - struct task_thread_times_info task_times; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - /* task_for_pid() requires special privileges - * "This function can be called only if the process is owned by the - * procmod group or if the caller is root." - * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ - err = task_for_pid(mach_task_self(), pid, &task); - if ( err == KERN_SUCCESS) { - info_count = TASK_BASIC_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) { - return AccessDenied(); - } - - // otherwise throw a runtime error with appropriate error code - return PyErr_Format(PyExc_RuntimeError, - "task_info(TASK_BASIC_INFO) failed"); - } - - info_count = TASK_THREAD_TIMES_INFO_COUNT; - err = task_info(task, TASK_THREAD_TIMES_INFO, - (task_info_t)&task_times, &info_count); - if (err != KERN_SUCCESS) { - // errcode 4 is "invalid argument" (access denied) - if (err == 4) { - return AccessDenied(); - } - return PyErr_Format(PyExc_RuntimeError, - "task_info(TASK_BASIC_INFO) failed"); - } - } - - else { // task_for_pid failed - if (! pid_exists(pid) ) { - return NoSuchProcess(); - } - // pid exists, so return AccessDenied error since task_for_pid() failed - return AccessDenied(); - } - - float user_t = -1.0; - float sys_t = -1.0; - user_time = tasks_info.user_time; - system_time = tasks_info.system_time; - - time_value_add(&user_time, &task_times.user_time); - time_value_add(&system_time, &task_times.system_time); - - user_t = (float)user_time.seconds + ((float)user_time.microseconds / 1000000.0); - sys_t = (float)system_time.seconds + ((float)system_time.microseconds / 1000000.0); - return Py_BuildValue("(dd)", user_t, sys_t); -} - - -/* - * 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; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime)); -} - - -/* - * Return a tuple of RSS and VMS memory usage. - */ -static PyObject* -get_memory_info(PyObject* self, PyObject* args) -{ - long pid; - int err; - unsigned int info_count = TASK_BASIC_INFO_COUNT; - mach_port_t task; - struct task_basic_info tasks_info; - vm_region_basic_info_data_64_t b_info; - vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; - vm_size_t size; - mach_port_t object_name; - - // the argument passed should be a process id - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - /* task_for_pid() requires special privileges - * "This function can be called only if the process is owned by the - * procmod group or if the caller is root." - * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ - err = task_for_pid(mach_task_self(), pid, &task); - if ( err == KERN_SUCCESS) { - info_count = TASK_BASIC_INFO_COUNT; - err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); - if (err != KERN_SUCCESS) { - if (err == 4) { - // errcode 4 is "invalid argument" (access denied) - return AccessDenied(); - } - // otherwise throw a runtime error with appropriate error code - return PyErr_Format(PyExc_RuntimeError, - "task_info(TASK_BASIC_INFO) failed"); - } - - /* Issue #73 http://code.google.com/p/psutil/issues/detail?id=73 - * adjust the virtual memory size down to account for - * shared memory that task_info.virtual_size includes w/every process - */ - info_count = VM_REGION_BASIC_INFO_COUNT_64; - err = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO, - (vm_region_info_t)&b_info, &info_count, &object_name); - if (err == KERN_SUCCESS) { - if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && - tasks_info.virtual_size > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) - { - tasks_info.virtual_size -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); - } - } - } - - else { - if (! pid_exists(pid) ) { - return NoSuchProcess(); - } - - // pid exists, so return AccessDenied error since task_for_pid() failed - return AccessDenied(); - } - - return Py_BuildValue("(ll)", tasks_info.resident_size, tasks_info.virtual_size); -} - - -/* - * Return number of threads used by process as a Python integer. - */ -static PyObject* -get_process_num_threads(PyObject* self, PyObject* args) -{ - long pid; - int err, ret; - unsigned int info_count = TASK_BASIC_INFO_COUNT; - mach_port_t task; - struct task_basic_info tasks_info; - thread_act_port_array_t thread_list; - mach_msg_type_number_t thread_count; - - // the argument passed should be a process id - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - /* task_for_pid() requires special privileges - * "This function can be called only if the process is owned by the - * procmod group or if the caller is root." - * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html - */ - err = task_for_pid(mach_task_self(), pid, &task); - if ( err == KERN_SUCCESS) { - info_count = TASK_BASIC_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) { - return AccessDenied(); - } - - // otherwise throw a runtime error with appropriate error code - return PyErr_Format(PyExc_RuntimeError, - "task_info(TASK_BASIC_INFO) failed"); - } - err = task_threads(task, &thread_list, &thread_count); - if (err == KERN_SUCCESS) { - ret = vm_deallocate(task, (vm_address_t)thread_list, - thread_count * sizeof(int)); - if (ret != KERN_SUCCESS) { - printf("vm_deallocate() failed\n"); - } - return Py_BuildValue("l", (long)thread_count); - } - else { - return PyErr_Format(PyExc_RuntimeError, "task_thread() failed"); - } - } - else { - if (! pid_exists(pid) ) { - return NoSuchProcess(); - } - - // pid exists, so return AccessDenied error since task_for_pid() failed - return AccessDenied(); - } - return NULL; -} - - -/* - * Return a Python integer indicating the total amount of physical memory - * in bytes. - */ -static PyObject* -get_total_phymem(PyObject* self, PyObject* args) -{ - int mib[2]; - uint64_t total_phymem; - size_t len; - - mib[0] = CTL_HW; - mib[1] = HW_MEMSIZE; - len = sizeof(total_phymem); - - if (sysctl(mib, 2, &total_phymem, &len, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - return Py_BuildValue("L", total_phymem); -} - - -/* - * Return a Python long indicating the amount of available physical memory in - * bytes. - */ -static PyObject* -get_avail_phymem(PyObject* self, PyObject* args) -{ - vm_statistics_data_t vm_stat; - mach_msg_type_number_t count; - kern_return_t error; - unsigned long long mem_free; - int pagesize = getpagesize(); - mach_port_t mport = mach_host_self(); - - count = sizeof(vm_stat) / sizeof(natural_t); - error = host_statistics(mport, HOST_VM_INFO, (host_info_t)&vm_stat, &count); - - if (error != KERN_SUCCESS) { - return PyErr_Format(PyExc_RuntimeError, - "Error in host_statistics(): %s", mach_error_string(error)); - } - - mem_free = (unsigned long long) vm_stat.free_count * pagesize; - return Py_BuildValue("L", mem_free); -} - - -/* - * Return a Python integer indicating the total amount of virtual memory - * in bytes. - */ -static PyObject* -get_total_virtmem(PyObject* self, PyObject* args) -{ - int mib[2]; - size_t size; - struct xsw_usage totals; - - mib[0] = CTL_VM; - mib[1] = VM_SWAPUSAGE; - size = sizeof(totals); - - if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - return Py_BuildValue("L", totals.xsu_total); -} - -/* - * Return a Python integer indicating the avail amount of virtual memory - * in bytes. - */ -static PyObject* -get_avail_virtmem(PyObject* self, PyObject* args) -{ - int mib[2]; - size_t size; - struct xsw_usage totals; - - mib[0] = CTL_VM; - mib[1] = VM_SWAPUSAGE; - size = sizeof(totals); - - if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - return Py_BuildValue("L", totals.xsu_avail); -} - -/* - * Return a Python tuple representing user, kernel and idle CPU times - */ -static PyObject* -get_system_cpu_times(PyObject* self, PyObject* args) -{ - mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT; - kern_return_t error; - host_cpu_load_info_data_t r_load; - - error = host_statistics(mach_host_self(), 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)); - } - - 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) -{ - 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; - PyObject* py_retlist = PyList_New(0); - PyObject* py_cputime; - int i, ret; - - error = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, - &cpu_count, &info_array, &info_count); - if (error != KERN_SUCCESS) { - return PyErr_Format(PyExc_RuntimeError, - "Error in host_processor_info(): %s", mach_error_string(error)); - } - - 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 - ); - PyList_Append(py_retlist, py_cputime); - Py_XDECREF(py_cputime); - } - - ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array, - info_count * sizeof(int)); - if (ret != KERN_SUCCESS) { - printf("vm_deallocate() failed\n"); - } - return py_retlist; -} - - -/* - * 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) -{ - /* 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); - return NULL; - } - boot_time = result.tv_sec; - return Py_BuildValue("f", (float)boot_time); -} - - -/* - * 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) -{ - int num; - int i; - long len; - struct statfs *fs; - PyObject* py_retlist = PyList_New(0); - PyObject* py_tuple; - - // get the number of mount points - Py_BEGIN_ALLOW_THREADS - num = getfsstat(NULL, 0, MNT_NOWAIT); - Py_END_ALLOW_THREADS - if (num == -1) { - PyErr_SetFromErrno(0); - return NULL; - } - - len = sizeof(*fs) * num; - fs = malloc(len); - - Py_BEGIN_ALLOW_THREADS - num = getfsstat(fs, len, MNT_NOWAIT); - Py_END_ALLOW_THREADS - if (num == -1) { - free(fs); - PyErr_SetFromErrno(0); - return NULL; - } - - for (i = 0; i < num; i++) { - py_tuple = Py_BuildValue("(sss)", fs[i].f_mntfromname, // device - fs[i].f_mntonname, // mount point - fs[i].f_fstypename); // fs type - PyList_Append(py_retlist, py_tuple); - Py_XDECREF(py_tuple); - } - - free(fs); - return py_retlist; -} - - -/* - * Return process status as a Python integer. - */ -static PyObject* -get_process_status(PyObject* self, PyObject* args) -{ - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - if (get_kinfo_proc(pid, &kp) == -1) { - return NULL; - } - return Py_BuildValue("i", (int)kp.kp_proc.p_stat); -} - - -/* - * Return process threads - */ -static PyObject* -get_process_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; - struct task_basic_info tasks_info; - thread_act_port_array_t thread_list; - thread_info_data_t thinfo; - 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; - - // the argument passed should be a process id - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - // task_for_pid() requires special privileges - err = task_for_pid(mach_task_self(), pid, &task); - if (err != KERN_SUCCESS) { - if (! pid_exists(pid) ) { - return NoSuchProcess(); - } - return AccessDenied(); - } - - info_count = TASK_BASIC_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) { - return AccessDenied(); - } - // otherwise throw a runtime error with appropriate error code - return PyErr_Format(PyExc_RuntimeError, - "task_info(TASK_BASIC_INFO) failed"); - } - - err = task_threads(task, &thread_list, &thread_count); - if (err != KERN_SUCCESS) { - return PyErr_Format(PyExc_RuntimeError, "task_threads() failed"); - } - - for (j = 0; j < thread_count; j++) { - thread_info_count = THREAD_INFO_MAX; - kr = thread_info(thread_list[j], THREAD_BASIC_INFO, - (thread_info_t)thinfo, &thread_info_count); - if (kr != KERN_SUCCESS) { - return PyErr_Format(PyExc_RuntimeError, "thread_info() failed"); - } - 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 - ); - PyList_Append(retList, pyTuple); - Py_XDECREF(pyTuple); - } - - ret = vm_deallocate(task, (vm_address_t)thread_list, - thread_count * sizeof(int)); - if (ret != KERN_SUCCESS) { - printf("vm_deallocate() failed\n"); - } - - return retList; -} - - -/* - * Return process open files as a Python tuple. - * References: - * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd - * - /usr/include/sys/proc_info.h - */ -static PyObject* -get_process_open_files(PyObject* self, PyObject* args) -{ - long pid; - int pidinfo_result; - int iterations; - int i; - int nb; - - struct proc_fdinfo *fds_pointer; - struct proc_fdinfo *fdp_pointer; - struct vnode_fdinfowithpath vi; - - PyObject *retList = PyList_New(0); - PyObject *tuple = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (pidinfo_result <= 0) { - goto error; - } - - fds_pointer = malloc(pidinfo_result); - pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer, - pidinfo_result); - free(fds_pointer); - - if (pidinfo_result <= 0) { - goto error; - } - - iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE); - - for (i = 0; i < iterations; i++) { - fdp_pointer = &fds_pointer[i]; - - // - if (fdp_pointer->proc_fdtype == PROX_FDTYPE_VNODE) - { - nb = proc_pidfdinfo(pid, - fdp_pointer->proc_fd, - PROC_PIDFDVNODEPATHINFO, - &vi, - sizeof(vi)); - - // --- errors checking - if (nb <= 0) { - if ((errno == ENOENT) || (errno == EBADF)) { - // no such file or directory or bad file descriptor; - // let's assume the file has been closed or removed - continue; - } - if (errno != 0) { - return PyErr_SetFromErrno(PyExc_OSError); - } - else - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed"); - } - if (nb < sizeof(vi)) { - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)"); - } - // --- /errors checking - - // --- construct python list - tuple = Py_BuildValue("(si)", vi.pvip.vip_path, - (int)fdp_pointer->proc_fd); - PyList_Append(retList, tuple); - Py_DECREF(tuple); - // --- /construct python list - } - } - - return retList; - -error: - if (errno != 0) - return PyErr_SetFromErrno(PyExc_OSError); - else if (! pid_exists(pid) ) - return NoSuchProcess(); - else - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDLISTFDS) failed"); -} - - -/* - * mathes Linux net/tcp_states.h: - * http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h - */ -static char * -get_connection_status(int st) { - switch (st) { - case TCPS_CLOSED: - return "CLOSE"; - case TCPS_CLOSING: - return "CLOSING"; - case TCPS_CLOSE_WAIT: - return "CLOSE_WAIT"; - case TCPS_LISTEN: - return "LISTEN"; - case TCPS_ESTABLISHED: - return "ESTABLISHED"; - case TCPS_SYN_SENT: - return "SYN_SENT"; - case TCPS_SYN_RECEIVED: - return "SYN_RECV"; - case TCPS_FIN_WAIT_1: - return "FIN_WAIT_1"; - case TCPS_FIN_WAIT_2: - return "FIN_WAIT_2"; - case TCPS_LAST_ACK: - return "LAST_ACK"; - case TCPS_TIME_WAIT: - return "TIME_WAIT"; - default: - return ""; - } -} - - -/* - * Return process TCP and UDP connections as a list of tuples. - * References: - * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0 - * - /usr/include/sys/proc_info.h - */ -static PyObject* -get_process_connections(PyObject* self, PyObject* args) -{ - long pid; - int pidinfo_result; - int iterations; - int i; - int nb; - - struct proc_fdinfo *fds_pointer; - struct proc_fdinfo *fdp_pointer; - struct socket_fdinfo si; - - - PyObject *retList = PyList_New(0); - PyObject *tuple = NULL; - PyObject *laddr = NULL; - PyObject *raddr = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - - if (pid == 0) { - return retList; - } - - pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (pidinfo_result <= 0) { - goto error; - } - - fds_pointer = malloc(pidinfo_result); - pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer, - pidinfo_result); - free(fds_pointer); - - if (pidinfo_result <= 0) { - goto error; - } - - iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE); - - for (i = 0; i < iterations; i++) { - errno = 0; - fdp_pointer = &fds_pointer[i]; - - // - if (fdp_pointer->proc_fdtype == PROX_FDTYPE_SOCKET) - { - nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd, PROC_PIDFDSOCKETINFO, - &si, sizeof(si)); - - // --- errors checking - if (nb <= 0) { - if (errno == EBADF) { - // let's assume socket has been closed - continue; - } - if (errno != 0) { - return PyErr_SetFromErrno(PyExc_OSError); - } - else { - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed"); - } - } - if (nb < sizeof(si)) { - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed (buffer mismatch)"); - } - // --- /errors checking - - // - int fd, family, type, lport, rport; - char lip[200], rip[200]; - char *state; - - fd = (int)fdp_pointer->proc_fd; - family = si.psi.soi_family; - type = si.psi.soi_kind; - - if ((family != AF_INET) && (family != AF_INET6)) { - continue; - } - - if (type == 2) - type = SOCK_STREAM; - else if (type == 1) - type = SOCK_DGRAM; - else - continue; - - if (errno != 0) { - printf("errno 1 = %i\n", errno); - return PyErr_SetFromErrno(PyExc_OSError); - } - - - if (family == AF_INET) { - inet_ntop(AF_INET, - &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_46.i46a_addr4, - lip, - sizeof(lip)); - inet_ntop(AF_INET, - &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_46.i46a_addr4, - rip, - sizeof(lip)); - } - else { - inet_ntop(AF_INET6, - &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_6, - lip, sizeof(lip)); - inet_ntop(AF_INET6, - &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_6, - lip, sizeof(rip)); - } - - // check for inet_ntop failures - if (errno != 0) { - return PyErr_SetFromErrno(PyExc_OSError); - } - - 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 = ""; - - laddr = Py_BuildValue("(si)", lip, lport); - if (rport != 0) - raddr = Py_BuildValue("(si)", rip, rport); - else - raddr = PyTuple_New(0); - - // --- construct python list - tuple = Py_BuildValue("(iiiNNs)", fd, family, type, laddr, raddr, - state); - PyList_Append(retList, tuple); - Py_DECREF(tuple); - // --- /construct python list - } - } - - return retList; - -error: - if (errno != 0) - return PyErr_SetFromErrno(PyExc_OSError); - else if (! pid_exists(pid) ) - return NoSuchProcess(); - else - return PyErr_Format(PyExc_RuntimeError, - "proc_pidinfo(PROC_PIDLISTFDS) failed"); -} - - -/* - * Return a Python list of named tuples with overall network I/O information - */ -static PyObject* -get_network_io_counters(PyObject* self, PyObject* args) -{ - PyObject* py_retdict = PyDict_New(); - PyObject* py_ifc_info; - - char *buf = NULL, *lim, *next; - struct if_msghdr *ifm; - int mib[6]; - size_t len; - - mib[0] = CTL_NET; // networking subsystem - mib[1] = PF_ROUTE; // type of information - mib[2] = 0; // protocol (IPPROTO_xxx) - mib[3] = 0; // address family - mib[4] = NET_RT_IFLIST2; // operation - mib[5] = 0; - - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { - Py_DECREF(py_retdict); - PyErr_SetFromErrno(0); - return NULL; - } - - buf = malloc(len); - - if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { - if (buf) { - free(buf); - } - Py_DECREF(py_retdict); - PyErr_SetFromErrno(0); - return NULL; - } - - lim = buf + len; - - for (next = buf; next < lim; ) { - ifm = (struct if_msghdr *)next; - next += ifm->ifm_msglen; - - if (ifm->ifm_type == RTM_IFINFO2) { - struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm; - struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1); - char ifc_name[32]; - - strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen); - ifc_name[sdl->sdl_nlen] = 0; - - py_ifc_info = Py_BuildValue("(KKKK)", - if2m->ifm_data.ifi_obytes, - if2m->ifm_data.ifi_ibytes, - if2m->ifm_data.ifi_opackets, - if2m->ifm_data.ifi_ipackets); - PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info); - Py_XDECREF(py_ifc_info); - } - else { - continue; - } - } - - free(buf); - - return py_retdict; -} - - -/* - * Return a Python dict of tuples for disk I/O information - */ -static PyObject* -get_disk_io_counters(PyObject* self, PyObject* args) -{ - PyObject* py_retdict = PyDict_New(); - PyObject* py_disk_info; - - CFDictionaryRef parent_dict; - CFDictionaryRef props_dict; - CFDictionaryRef stats_dict; - io_registry_entry_t parent; - io_registry_entry_t disk; - io_iterator_t disk_list; - - /* Get list of disks */ - if (IOServiceGetMatchingServices(kIOMasterPortDefault, - IOServiceMatching(kIOMediaClass), - &disk_list) != kIOReturnSuccess) { - Py_DECREF(py_retdict); - PyErr_SetString(PyExc_RuntimeError, "Unable to get the list of disks."); - return NULL; - } - - /* Iterate over disks */ - while ((disk = IOIteratorNext(disk_list)) != 0) { - 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."); - Py_DECREF(py_retdict); - IOObjectRelease(disk); - return NULL; - } - - if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) { - if(IORegistryEntryCreateCFProperties( - disk, - (CFMutableDictionaryRef *) &parent_dict, - kCFAllocatorDefault, - kNilOptions) != kIOReturnSuccess) - { - PyErr_SetString(PyExc_RuntimeError, - "Unable to get the parent's properties."); - Py_DECREF(py_retdict); - IOObjectRelease(disk); - IOObjectRelease(parent); - return NULL; - } - - if (IORegistryEntryCreateCFProperties(parent, - (CFMutableDictionaryRef *) &props_dict, - kCFAllocatorDefault, - kNilOptions) != kIOReturnSuccess) - { - PyErr_SetString(PyExc_RuntimeError, - "Unable to get the disk properties."); - Py_DECREF(py_retdict); - IOObjectRelease(disk); - return NULL; - } - - const int kMaxDiskNameSize = 64; - CFStringRef disk_name_ref = (CFStringRef)CFDictionaryGetValue( - parent_dict, - CFSTR(kIOBSDNameKey)); - char disk_name[kMaxDiskNameSize]; - - CFStringGetCString(disk_name_ref, - disk_name, - kMaxDiskNameSize, - CFStringGetSystemEncoding()); - - stats_dict = (CFDictionaryRef)CFDictionaryGetValue( - props_dict, - CFSTR(kIOBlockStorageDriverStatisticsKey)); - - if (stats_dict == NULL) { - PyErr_SetString(PyExc_RuntimeError, "Unable to get disk stats."); - Py_DECREF(py_retdict); - CFRelease(props_dict); - IOObjectRelease(disk); - IOObjectRelease(parent); - return NULL; - } - - CFNumberRef number; - int64_t reads, writes, read_bytes, write_bytes, read_time, write_time = 0; - - /* Get disk reads/writes */ - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) - { - CFNumberGetValue(number, kCFNumberSInt64Type, &reads); - } - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) - { - CFNumberGetValue(number, kCFNumberSInt64Type, &writes); - } - - /* Get disk bytes read/written */ - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) - { - CFNumberGetValue(number, kCFNumberSInt64Type, &read_bytes); - } - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) - { - CFNumberGetValue(number, kCFNumberSInt64Type, &write_bytes); - } - - /* Get disk time spent reading/writing (nanoseconds) */ - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey)))) - { - CFNumberGetValue(number, kCFNumberSInt64Type, &read_time); - } - if ((number = (CFNumberRef)CFDictionaryGetValue( - stats_dict, - CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)))) { - CFNumberGetValue(number, kCFNumberSInt64Type, &write_time); - } - - py_disk_info = Py_BuildValue("(KKKKKK)", - reads, writes, - read_bytes, write_bytes, - read_time, write_time); - PyDict_SetItemString(py_retdict, disk_name, py_disk_info); - Py_XDECREF(py_disk_info); - - CFRelease(parent_dict); - IOObjectRelease(parent); - CFRelease(props_dict); - IOObjectRelease(disk); - } - } - - IOObjectRelease (disk_list); - - return py_retdict; -} - - -/* - * define the psutil C module methods and initialize the module. - */ -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_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_cpu_times", get_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_memory_info", get_memory_info, METH_VARARGS, - "Return a tuple of RSS/VMS memory information"}, - {"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_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"}, - - // --- 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_total_phymem", get_total_phymem, METH_VARARGS, - "Return the total amount of physical memory, in bytes"}, - {"get_avail_phymem", get_avail_phymem, METH_VARARGS, - "Return the amount of available physical memory, in bytes"}, - {"get_total_virtmem", get_total_virtmem, METH_VARARGS, - "Return the total amount of virtual memory, in bytes"}, - {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS, - "Return the amount of available virtual 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 a float indicating 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."}, - - {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_osx_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int -psutil_osx_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - return 0; -} - - -static struct PyModuleDef -moduledef = { - PyModuleDef_HEAD_INIT, - "psutil_osx", - NULL, - sizeof(struct module_state), - PsutilMethods, - NULL, - psutil_osx_traverse, - psutil_osx_clear, - NULL -}; - -#define INITERROR return NULL - -PyObject * -PyInit__psutil_osx(void) - -#else -#define INITERROR return - -void -init_psutil_osx(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("_psutil_osx", PsutilMethods); -#endif - // process status constants, defined in: - // http://fxr.watson.org/fxr/source/bsd/sys/proc.h?v=xnu-792.6.70#L149 - PyModule_AddIntConstant(module, "SIDL", SIDL); - PyModule_AddIntConstant(module, "SRUN", SRUN); - PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); - PyModule_AddIntConstant(module, "SSTOP", SSTOP); - PyModule_AddIntConstant(module, "SZOMB", SZOMB); - - if (module == NULL) { - INITERROR; - } -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} diff --git a/third_party/psutil/psutil/_psutil_osx.h b/third_party/psutil/psutil/_psutil_osx.h deleted file mode 100644 index a0378a7..0000000 --- a/third_party/psutil/psutil/_psutil_osx.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * $Id: _psutil_osx.h 1142 2011-10-05 18:45:49Z 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. - * - * 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_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_cpu_times(PyObject* self, PyObject* args); -static PyObject* get_process_create_time(PyObject* self, PyObject* args); -static PyObject* get_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_tty_nr(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_total_phymem(PyObject* self, PyObject* args); -static PyObject* get_avail_phymem(PyObject* self, PyObject* args); -static PyObject* get_total_virtmem(PyObject* self, PyObject* args); -static PyObject* get_avail_virtmem(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); diff --git a/third_party/psutil/psutil/_psutil_posix.c b/third_party/psutil/psutil/_psutil_posix.c deleted file mode 100644 index 6a530f0..0000000 --- a/third_party/psutil/psutil/_psutil_posix.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * $Id: _psutil_posix.c 1142 2011-10-05 18:45:49Z 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. - * - * Functions specific to all POSIX compliant platforms. - */ - -#include <Python.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/resource.h> - -#include "_psutil_posix.h" - - -/* - * Given a PID return process priority as a Python integer. - */ -static PyObject* -posix_getpriority(PyObject* self, PyObject* args) -{ - long pid; - int priority; - errno = 0; - if (! PyArg_ParseTuple(args, "l", &pid)) { - return NULL; - } - priority = getpriority(PRIO_PROCESS, pid); - 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) -{ - long pid; - int priority; - int retval; - if (! PyArg_ParseTuple(args, "li", &pid, &priority)) { - return NULL; - } - retval = setpriority(PRIO_PROCESS, pid, priority); - if (retval == -1) { - return PyErr_SetFromErrno(PyExc_OSError); - } - Py_INCREF(Py_None); - return Py_None; -} - - -/* - * 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} -}; - -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_posix_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int -psutil_posix_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - 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 -}; - -#define INITERROR return NULL - -PyObject * -PyInit__psutil_posix(void) - -#else -#define INITERROR return - -void init_psutil_posix(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods); -#endif - if (module == NULL) { - INITERROR; - } -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} - - - diff --git a/third_party/psutil/psutil/_psutil_posix.h b/third_party/psutil/psutil/_psutil_posix.h deleted file mode 100644 index 8a1f522..0000000 --- a/third_party/psutil/psutil/_psutil_posix.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * $Id: _psutil_posix.h 1142 2011-10-05 18:45:49Z 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. - * - * 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); - diff --git a/third_party/psutil/psutil/arch/bsd/process_info.c b/third_party/psutil/psutil/arch/bsd/process_info.c deleted file mode 100644 index d300646..0000000 --- a/third_party/psutil/psutil/arch/bsd/process_info.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * $Id: process_info.c 1142 2011-10-05 18:45:49Z 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. - * - * Helper functions related to fetching process information. Used by _psutil_bsd - * module methods. - */ - -#include <Python.h> -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/sysctl.h> -#include <sys/param.h> -#include <sys/user.h> -#include <sys/proc.h> - -#include "process_info.h" - - -/* - * 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 - * number of entries in *procCount. You are responsible for freeing - * this list (use "free" from System framework). - * On success, the function returns 0. - * On error, the function returns a BSD errno value. - */ -int -get_proc_list(struct kinfo_proc **procList, size_t *procCount) -{ - int err; - 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 - // sysctl because the prototype doesn't include the const modifier. - size_t length; - - assert( procList != NULL); - assert(*procList == NULL); - assert(procCount != NULL); - - *procCount = 0; - - /* - * We start by calling sysctl with result == NULL and length == 0. - * That will succeed, and set length to the appropriate length. - * We then allocate a buffer of that size and call sysctl again - * with that buffer. If that succeeds, we're done. If that fails - * with ENOMEM, we have to throw away our buffer and loop. Note - * that the loop causes use to call sysctl with NULL again; this - * is necessary because the ENOMEM failure case sets length to - * the amount of data returned, not the amount of data that - * could have been returned. - */ - result = NULL; - done = 0; - do { - assert(result == NULL); - // Call sysctl with a NULL buffer. - length = 0; - err = sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1, - NULL, &length, NULL, 0); - if (err == -1) - err = errno; - - // Allocate an appropriately sized buffer based on the results - // from the previous call. - if (err == 0) { - result = malloc(length); - if (result == NULL) - err = ENOMEM; - } - - // Call sysctl again with the new buffer. If we get an ENOMEM - // error, toss away our buffer and start again. - if (err == 0) { - err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1, - result, &length, NULL, 0); - if (err == -1) - err = errno; - if (err == 0) { - done = 1; - } - else if (err == ENOMEM) { - assert(result != NULL); - free(result); - result = NULL; - err = 0; - } - } - } while (err == 0 && ! done); - - // Clean up and establish post conditions. - if (err != 0 && result != NULL) { - free(result); - result = NULL; - } - - *procList = result; - *procCount = length / sizeof(struct kinfo_proc); - - assert((err == 0) == (*procList != NULL)); - return err; -} - - -char -*getcmdpath(long pid, size_t *pathsize) -{ - int mib[4]; - char *path; - size_t size = 0; - - /* - * Make a sysctl() call to get the raw argument space of the process. - */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - 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) { - return NULL; - } - - path = malloc(size); - if (path == NULL) - return NULL; - - *pathsize = size; - if (sysctl(mib, 4, path, &size, NULL, 0) == -1) { - free(path); - return NULL; /* Insufficient privileges */ - } - - return path; -} - - - -/* - * Borrowed from psi Python System Information project - * - * Get command arguments and environment variables. - * - * Based on code from ps. - * - * Returns: - * 0 for success; - * -1 for failure (Exception raised); - * 1 for insufficient privileges. - */ -char -*getcmdargs(long pid, size_t *argsize) -{ - int mib[4]; - size_t size, argmax; - char *procargs = NULL; - - /* Get the maximum process arguments size. */ - mib[0] = CTL_KERN; - mib[1] = KERN_ARGMAX; - - size = sizeof(argmax); - if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) - return NULL; - - /* Allocate space for the arguments. */ - procargs = (char *)malloc(argmax); - if (procargs == NULL) - return NULL; - - /* - * Make a sysctl() call to get the raw argument space of the process. - */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_ARGS; - mib[3] = pid; - - size = argmax; - if (sysctl(mib, 4, procargs, &size, NULL, 0) == -1) { - free(procargs); - return NULL; /* Insufficient privileges */ - } - - // return string and set the length of arguments - *argsize = size; - return procargs; -} - - -/* returns the command line as a python list object */ -PyObject* -get_arg_list(long pid) -{ - char *argstr = NULL; - int pos = 0; - size_t argsize = 0; - PyObject *retlist = Py_BuildValue("[]"); - PyObject *item = NULL; - - if (pid < 0) { - return retlist; - } - - // XXX - this leaks memory (grrr) - argstr = getcmdargs(pid, &argsize); - - if (NULL == argstr) { - if (ESRCH == errno) { - PyErr_Format(PyExc_RuntimeError, - "getcmdargs() failed - no process found with pid %lu", pid); - return NULL; - } - - // ignore other errors for now, since we don't want to bail on - // get_process_info() if cmdline is the only thing we couldn't get. - // In that case, we just return an empty list return - // PyErr_Format(PyExc_RuntimeError, "getcmdargs() failed for pid %lu", pid); - return retlist; - } - - // 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) { - item = Py_BuildValue("s", &argstr[pos]); - PyList_Append(retlist, item); - Py_DECREF(item); - pos = pos + strlen(&argstr[pos]) + 1; - } - } - - free(argstr); - return retlist; -} - - -/* - * Return 1 if PID exists in the current process list, else 0. - */ -int -pid_exists(long pid) -{ - int kill_ret; - 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)) { - return 1; - } - - // otherwise return 0 for PID not found - return 0; -} - diff --git a/third_party/psutil/psutil/arch/bsd/process_info.h b/third_party/psutil/psutil/arch/bsd/process_info.h deleted file mode 100644 index 9129153..0000000 --- a/third_party/psutil/psutil/arch/bsd/process_info.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * $Id: process_info.h 1142 2011-10-05 18:45:49Z 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. - * - * Helper functions related to fetching process information. Used by _psutil_bsd - * module methods. - */ - -#include <Python.h> - -typedef struct kinfo_proc kinfo_proc; - -int get_proc_list(struct kinfo_proc **procList, size_t *procCount); -char *getcmdargs(long pid, size_t *argsize); -char *getcmdpath(long pid, size_t *pathsize); -PyObject* get_arg_list(long pid); -int pid_exists(long pid); - diff --git a/third_party/psutil/psutil/arch/mswindows/ntextapi.h b/third_party/psutil/psutil/arch/mswindows/ntextapi.h deleted file mode 100644 index bb89923..0000000 --- a/third_party/psutil/psutil/arch/mswindows/ntextapi.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * $Id: ntextapi.h 1142 2011-10-05 18:45:49Z 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. - * - */ - -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; - ULONG 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; - - diff --git a/third_party/psutil/psutil/arch/mswindows/process_handles.c b/third_party/psutil/psutil/arch/mswindows/process_handles.c deleted file mode 100644 index 0fc4a3f..0000000 --- a/third_party/psutil/psutil/arch/mswindows/process_handles.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * $Id: process_handles.c 1142 2011-10-05 18:45:49Z 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. - * - */ - -#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* -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; - - - - handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); - - /* 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"); - return NULL; - } - - for (i = 0; i < handleInfo->HandleCount; i++) - { - SYSTEM_HANDLE handle = handleInfo->Handles[i]; - HANDLE dupHandle = NULL; - POBJECT_TYPE_INFORMATION objectTypeInfo; - PVOID objectNameInfo; - UNICODE_STRING objectName; - ULONG returnLength; - - /* Check if this handle belongs to the PID the user specified. */ - if (handle.ProcessId != pid) - continue; - - /* Skip handles with the following access codes as the next call - to NtDuplicateObject() or NtQueryObject() might hang forever. */ - if((handle.GrantedAccess == 0x0012019f) - || (handle.GrantedAccess == 0x001a019f) - || (handle.GrantedAccess == 0x00120189) - || (handle.GrantedAccess == 0x00100000)) { - continue; - } - - /* Duplicate the handle so we can query it. */ - if (!NT_SUCCESS(NtDuplicateObject( - processHandle, - handle.Handle, - GetCurrentProcess(), - &dupHandle, - 0, - 0, - 0 - ))) - { - //printf("[%#x] Error!\n", handle.Handle); - continue; - } - - /* Query the object type. */ - objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); - if (!NT_SUCCESS(NtQueryObject( - dupHandle, - ObjectTypeInformation, - objectTypeInfo, - 0x1000, - NULL - ))) - { - //printf("[%#x] Error!\n", handle.Handle); - CloseHandle(dupHandle); - continue; - } - - objectNameInfo = malloc(0x1000); - if (!NT_SUCCESS(NtQueryObject( - dupHandle, - ObjectNameInformation, - objectNameInfo, - 0x1000, - &returnLength - ))) - { - /* Reallocate the buffer and try again. */ - objectNameInfo = realloc(objectNameInfo, returnLength); - if (!NT_SUCCESS(NtQueryObject( - dupHandle, - ObjectNameInformation, - objectNameInfo, - returnLength, - NULL - ))) - { - /* We have the type name, so just display that.*/ - /* - printf( - "[%#x] %.*S: (could not get name)\n", - handle.Handle, - objectTypeInfo->Name.Length / 2, - objectTypeInfo->Name.Buffer - ); - */ - free(objectTypeInfo); - free(objectNameInfo); - CloseHandle(dupHandle); - continue; - - } - } - - /* Cast our buffer into an UNICODE_STRING. */ - objectName = *(PUNICODE_STRING)objectNameInfo; - - /* Print the information! */ - if (objectName.Length) - { - /* The object has a name. Make sure it is a file otherwise - ignore it */ - fileNameLength = objectName.Length / 2; - if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) { - //printf("%.*S\n", objectName.Length / 2, objectName.Buffer); - fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer, - fileNameLength); - #if PY_MAJOR_VERSION >= 3 - arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar)); - #else - arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar)); - #endif - Py_XDECREF(fileFromWchar); - PyList_Append(filesList, arg); - Py_XDECREF(arg); - } - /* - printf( - "[%#x] %.*S: %.*S\n", - handle.Handle, - objectTypeInfo->Name.Length / 2, - objectTypeInfo->Name.Buffer, - objectName.Length / 2, - objectName.Buffer - ); - */ - } - else - { - /* Print something else. */ - /* - printf( - "[%#x] %.*S: (unnamed)\n", - handle.Handle, - objectTypeInfo->Name.Length / 2, - objectTypeInfo->Name.Buffer - ); - */ - ;; - } - free(objectTypeInfo); - free(objectNameInfo); - CloseHandle(dupHandle); - } - free(handleInfo); - CloseHandle(processHandle); - return filesList; -} - diff --git a/third_party/psutil/psutil/arch/mswindows/process_handles.h b/third_party/psutil/psutil/arch/mswindows/process_handles.h deleted file mode 100644 index 3d007b8..0000000 --- a/third_party/psutil/psutil/arch/mswindows/process_handles.h +++ /dev/null @@ -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* get_open_files(long pid, HANDLE processHandle); diff --git a/third_party/psutil/psutil/arch/mswindows/process_info.c b/third_party/psutil/psutil/arch/mswindows/process_info.c deleted file mode 100644 index 53b1480..0000000 --- a/third_party/psutil/psutil/arch/mswindows/process_info.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * $Id: process_info.c 1142 2011-10-05 18:45:49Z 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. - * - * 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" - -/* - * NtQueryInformationProcess code taken from - * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/ - * typedefs needed to compile against ntdll functions not exposted in the API - */ -typedef LONG NTSTATUS; - -typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)( - HANDLE ProcessHandle, - DWORD ProcessInformationClass, - PVOID ProcessInformation, - DWORD ProcessInformationLength, - PDWORD ReturnLength - ); - -typedef struct _PROCESS_BASIC_INFORMATION -{ - PVOID Reserved1; - PVOID PebBaseAddress; - PVOID Reserved2[2]; - ULONG_PTR UniqueProcessId; - PVOID Reserved3; -} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; - - -/* - * 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 -handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess) -{ - HANDLE hProcess; - DWORD processExitCode = 0; - - 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 handle_from_pid_waccess but implicitly uses - * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess - * parameter for OpenProcess. - */ -HANDLE -handle_from_pid(DWORD pid) { - DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; - return handle_from_pid_waccess(pid, dwDesiredAccess); -} - - -// fetch the PEB base address from NtQueryInformationProcess() -PVOID -GetPebAddress(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* -get_pids(DWORD *numberOfReturnedPIDs) { - int procArraySz = 1024; - - /* 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; - - /* Stores the byte size of the returned array from enumprocesses */ - DWORD enumReturnSz = 0; - - do { - free(procArray); - procArrayByteSz = procArraySz * sizeof(DWORD); - procArray = malloc(procArrayByteSz); - - if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) { - free(procArray); - PyErr_SetFromWindowsErr(0); - return NULL; - } - else if (enumReturnSz == procArrayByteSz) { - /* Process list was too large. Allocate more space*/ - procArraySz += 1024; - } - - /* else we have a good list */ - - } while(enumReturnSz == procArraySz * sizeof(DWORD)); - - /* The number of elements is the returned size / size of each element */ - *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD); - - return procArray; -} - - -int -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 -pid_in_proclist(DWORD pid) -{ - DWORD *proclist = NULL; - DWORD numberOfReturnedPIDs; - DWORD i; - - proclist = 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 -BOOL is_running(HANDLE hProcess) -{ - DWORD dwCode; - - if (NULL == hProcess) { - return FALSE; - } - - if (GetExitCodeProcess(hProcess, &dwCode)) { - return (dwCode == STILL_ACTIVE); - } - return FALSE; -} - - -// Return None to represent NoSuchProcess, else return NULL for -// other exception or the name as a Python string -PyObject* -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* -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) { - ////printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID); - 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* -get_arg_list(long pid) -{ - int nArgs, i; - LPWSTR *szArglist; - HANDLE hProcess; - PVOID pebAddress; - PVOID rtlUserProcParamsAddress; - UNICODE_STRING commandLine; - WCHAR *commandLineContents; - PyObject *arg = NULL; - PyObject *arg_from_wchar = NULL; - PyObject *argList = NULL; - - hProcess = handle_from_pid(pid); - if(hProcess == NULL) { - return NULL; - } - - pebAddress = GetPebAddress(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); - CloseHandle(hProcess); - return NULL; - } - - /* 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"); - CloseHandle(hProcess); - PyErr_SetFromWindowsErr(0); - return NULL; - } - - - /* allocate memory to hold the command line */ - commandLineContents = (WCHAR *)malloc(commandLine.Length+1); - - /* read the command line */ - if (!ReadProcessMemory(hProcess, commandLine.Buffer, - commandLineContents, commandLine.Length, NULL)) - { - ////printf("Could not read the command line string!\n"); - CloseHandle(hProcess); - PyErr_SetFromWindowsErr(0); - free(commandLineContents); - return NULL; - } - - /* 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 PY_MAJOR_VERSION >= 3 - argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar)); - #else - argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar)); - #endif - } - else { - // arglist parsed as array of UNICODE_STRING, so convert each to Python - // string object and add to arg list - argList = Py_BuildValue("[]"); - for(i=0; i<nArgs; i++) { - ////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 PY_MAJOR_VERSION >= 3 - arg = PyUnicode_FromObject(arg_from_wchar); - #else - arg = PyUnicode_AsUTF8String(arg_from_wchar); - #endif - Py_XDECREF(arg_from_wchar); - PyList_Append(argList, arg); - Py_XDECREF(arg); - } - } - - LocalFree(szArglist); - free(commandLineContents); - CloseHandle(hProcess); - return argList; -} - - -#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); - - while (TRUE) { - status = NtQuerySystemInformation(SystemProcessInformation, buffer, - bufferSize, &bufferSize); - - if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) - { - free(buffer); - buffer = malloc(bufferSize); - } - else { - break; - } - } - - if (status != 0) { - PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed"); - return 0; - } - - 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(); - return 0; -} - - diff --git a/third_party/psutil/psutil/arch/mswindows/process_info.h b/third_party/psutil/psutil/arch/mswindows/process_info.h deleted file mode 100644 index e7a855c..0000000 --- a/third_party/psutil/psutil/arch/mswindows/process_info.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * $Id: process_info.h 1142 2011-10-05 18:45:49Z 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. - * - * Helper functions related to fetching process information. Used by _psutil_mswindows - * module methods. - */ - -#include <Python.h> -#include <windows.h> - -HANDLE handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess); -HANDLE handle_from_pid(DWORD pid); -PVOID GetPebAddress(HANDLE ProcessHandle); -HANDLE handle_from_pid(DWORD pid); -BOOL is_running(HANDLE hProcess); -int pid_in_proclist(DWORD pid); -int pid_is_running(DWORD pid); -PyObject* get_arg_list(long pid); -PyObject* get_ppid(long pid); -PyObject* get_name(long pid); -DWORD* get_pids(DWORD *numberOfReturnedPIDs); diff --git a/third_party/psutil/psutil/arch/mswindows/security.c b/third_party/psutil/psutil/arch/mswindows/security.c deleted file mode 100644 index 5a07df2f..0000000 --- a/third_party/psutil/psutil/arch/mswindows/security.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * $Id: security.c 1142 2011-10-05 18:45:49Z 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. - * - * Security related functions for Windows platform (Set privileges such as - * SeDebug), as well as security helper functions. - */ - -#include <windows.h> -#include <Python.h> - -/* - * Convert a process handle to a process token handle. - */ -HANDLE -token_from_handle(HANDLE hProcess) { - HANDLE hToken = NULL; - - if (! OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) ) { - return PyErr_SetFromWindowsErr(0); - } - - return hToken; -} - - -/* - * http://www.ddj.com/windows/184405986 - * - * There's a way to determine whether we're running under the Local System - * account. However (you guessed it), we have to call more Win32 functions to - * determine this. Backing up through the code listing, we need to make another - * call to GetTokenInformation, but instead of passing through the TOKEN_USER - * constant, we pass through the TOKEN_PRIVILEGES constant. This value returns - * an array of privileges that the account has in the environment. Iterating - * through the array, we call the function LookupPrivilegeName looking for the - * string “SeTcbPrivilege. If the function returns this string, then this - * account has Local System privileges - */ -int HasSystemPrivilege(HANDLE hProcess) { - DWORD i; - DWORD dwSize = 0; - DWORD dwRetval = 0; - TCHAR privName[256]; - DWORD dwNameSize = 256; - //PTOKEN_PRIVILEGES tp = NULL; - BYTE *pBuffer = NULL; - TOKEN_PRIVILEGES* tp = NULL; - HANDLE hToken = token_from_handle(hProcess); - - if (NULL == hToken) { - return -1; - } - - // call GetTokenInformation first to get the buffer size - if (! GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) { - dwRetval = GetLastError(); - // if it failed for a reason other than the buffer, bail out - if (dwRetval != ERROR_INSUFFICIENT_BUFFER ) { - PyErr_SetFromWindowsErr(dwRetval); - return 0; - } - } - - // allocate buffer and call GetTokenInformation again - //tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize); - pBuffer = (BYTE *) malloc(dwSize); - - if (pBuffer == NULL) { - PyErr_SetFromWindowsErr(0); - LocalFree(pBuffer); - return -1; - } - - if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwSize, &dwSize) ) { - PyErr_SetFromWindowsErr(0); - LocalFree(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; -} - diff --git a/third_party/psutil/psutil/arch/mswindows/security.h b/third_party/psutil/psutil/arch/mswindows/security.h deleted file mode 100644 index 2cfce29..0000000 --- a/third_party/psutil/psutil/arch/mswindows/security.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * $Id: security.h 1142 2011-10-05 18:45:49Z 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. - * - * 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); - diff --git a/third_party/psutil/psutil/arch/osx/process_info.c b/third_party/psutil/psutil/arch/osx/process_info.c deleted file mode 100644 index ae7d407..0000000 --- a/third_party/psutil/psutil/arch/osx/process_info.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * $Id: process_info.c 1142 2011-10-05 18:45:49Z 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. - * - * 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 <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <signal.h> -#include <sys/sysctl.h> - -#include "process_info.h" -#include "../../_psutil_common.h" - - -/* - * Return 1 if PID exists in the current process list, else 0. - */ -int -pid_exists(long pid) -{ - int kill_ret; - - // save some time if it's an invalid PID - 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) ) { - 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 - * number of entries in *procCount. You are responsible for freeing - * this list (use "free" from System framework). - * On success, the function returns 0. - * On error, the function returns a BSD errno value. - */ -int -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. */ - static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; - size_t size, size2; - void *ptr; - int err, lim = 8; /* some limit */ - - assert( procList != NULL); - assert(*procList == NULL); - assert(procCount != NULL); - - *procCount = 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. - * If that call fails with ENOMEM, we throw the buffer away - * and try again. - * Note that the loop calls sysctl with NULL again. This is - * is necessary because the ENOMEM failure case sets size to - * the amount of data returned, not the amount of data that - * could have been returned. - */ - while (lim-- > 0) { - size = 0; - if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1) { - return errno; - } - - size2 = size + (size >> 3); /* add some */ - if (size2 > size) { - ptr = malloc(size2); - if (ptr == NULL) { - ptr = malloc(size); - } else { - size = size2; - } - } - else { - ptr = malloc(size); - } - if (ptr == NULL) { - return ENOMEM; - } - - if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) { - err = errno; - free(ptr); - if (err != ENOMEM) { - return err; - } - - } else { - *procList = (kinfo_proc *)ptr; - *procCount = size / sizeof(kinfo_proc); - return 0; - } - } - return ENOMEM; -} - - -/* Read the maximum argument size for processes */ -int -get_argmax() -{ - int argmax; - int mib[] = { CTL_KERN, KERN_ARGMAX }; - size_t size = sizeof(argmax); - - if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0) { - return argmax; - } - return 0; -} - - -/* return process args as a python list */ -PyObject* -get_arg_list(long pid) -{ - int mib[3]; - int nargs; - int len; - char *procargs; - char *arg_ptr; - char *arg_end; - char *curr_arg; - size_t argmax; - PyObject *arg = NULL; - PyObject *arglist = NULL; - - //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. */ - argmax = get_argmax(); - if (! argmax) { return PyErr_SetFromErrno(PyExc_OSError); } - - procargs = (char *)malloc(argmax); - if (NULL == procargs) { - return PyErr_SetFromErrno(PyExc_OSError); - } - - /* 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 ( pid_exists(pid) ) { - AccessDenied(); - } else { - NoSuchProcess(); - } - } - free(procargs); - return NULL; - } - - arg_end = &procargs[argmax]; - /* copy the number of arguments to nargs */ - memcpy(&nargs, procargs, sizeof(nargs)); - - arg_ptr = procargs + sizeof(nargs); - len = strlen(arg_ptr); - arg_ptr += len + 1; - - if (arg_ptr == arg_end) { - free(procargs); - return Py_BuildValue("[]"); - } - - // skip ahead to the first argument - for (; arg_ptr < arg_end; arg_ptr++) { - if (*arg_ptr != '\0') { - break; - } - } - - /* iterate through arguments */ - curr_arg = arg_ptr; - arglist = Py_BuildValue("[]"); - while (arg_ptr < arg_end && nargs > 0) { - if (*arg_ptr++ == '\0') { - arg = Py_BuildValue("s", curr_arg); - if (NULL == arg) { - return NULL; - } - PyList_Append(arglist, arg); - Py_DECREF(arg); - // iterate to next arg and decrement # of args - curr_arg = arg_ptr; - nargs--; - } - } - - free(procargs); - return arglist; -} - - -int -get_kinfo_proc(pid_t pid, struct kinfo_proc *kp) -{ - int mib[4]; - size_t len; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = pid; - - // fetch the info with sysctl() - len = sizeof(struct kinfo_proc); - - // now read the data from sysctl - if (sysctl(mib, 4, kp, &len, NULL, 0) == -1) { - // raise an exception and throw errno as the error - PyErr_SetFromErrno(PyExc_OSError); - } - - /* - * sysctl succeeds but len is zero, happens when process has gone away - */ - if (len == 0) { - NoSuchProcess(); - return -1; - } - return 0; -} diff --git a/third_party/psutil/psutil/arch/osx/process_info.h b/third_party/psutil/psutil/arch/osx/process_info.h deleted file mode 100644 index 5939284..0000000 --- a/third_party/psutil/psutil/arch/osx/process_info.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * $Id: process_info.h 1142 2011-10-05 18:45:49Z 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. - * - * Helper functions related to fetching process information. Used by _psutil_osx - * module methods. - */ - -#include <Python.h> - - -typedef struct kinfo_proc kinfo_proc; - -int get_proc_list(kinfo_proc **procList, size_t *procCount); -int get_kinfo_proc(pid_t pid, struct kinfo_proc *kp); -int get_argmax(void); -int pid_exists(long pid); -PyObject* get_arg_list(long pid); diff --git a/third_party/psutil/psutil/error.py b/third_party/psutil/psutil/error.py deleted file mode 100644 index 0298cb9..0000000 --- a/third_party/psutil/psutil/error.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -# -# $Id: error.py 1142 2011-10-05 18:45:49Z 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. - -"""psutil exception classes; do not import this directly""" - - -class Error(Exception): - """Base exception class. All other psutil exceptions inherit - from this one. - """ - -class NoSuchProcess(Error): - """Exception raised when a process with a certain PID doesn't - or no longer exists (zombie). - """ - - def __init__(self, pid, name=None, msg=None): - self.pid = pid - self.name = name - self.msg = msg - if msg is None: - if name: - details = "(pid=%s, name=%s)" % (self.pid, repr(self.name)) - else: - details = "(pid=%s)" % self.pid - self.msg = "process no longer exists " + details - - def __str__(self): - return self.msg - - -class AccessDenied(Error): - """Exception raised when permission to perform an action is denied.""" - - def __init__(self, pid=None, name=None, msg=None): - self.pid = pid - self.name = name - self.msg = msg - if msg is None: - if (pid is not None) and (name is not None): - self.msg = "(pid=%s, name=%s)" % (pid, repr(name)) - elif (pid is not None): - self.msg = "(pid=%s)" % self.pid - else: - self.msg = "" - - def __str__(self): - return self.msg - - -class TimeoutExpired(Error): - """Raised on Process.wait(timeout) if timeout expires and process - is still alive. - """ - - def __init__(self, pid=None, name=None): - self.pid = pid - self.name = name - if (pid is not None) and (name is not None): - self.msg = "(pid=%s, name=%s)" % (pid, repr(name)) - elif (pid is not None): - self.msg = "(pid=%s)" % self.pid - else: - self.msg = "" - - def __str__(self): - return self.msg - diff --git a/third_party/psutil/setup.py b/third_party/psutil/setup.py deleted file mode 100644 index d7383cb..0000000 --- a/third_party/psutil/setup.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python -# -# $Id: setup.py 1142 2011-10-05 18:45:49Z 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. - -import sys -import os -try: - from setuptools import setup, Extension -except ImportError: - from distutils.core import setup, Extension - -__ver__ = "0.3.1" - -# Hack for Python 3 to tell distutils to run 2to3 against the files -# copied in the build directory before installing. -# Reference: http://docs.python.org/dev/howto/pyporting.html#during-installation -try: - from distutils.command.build_py import build_py_2to3 as build_py -except ImportError: - from distutils.command.build_py import build_py - - -if os.name == 'posix': - posix_extension = Extension('_psutil_posix', - sources = ['psutil/_psutil_posix.c']) - - -# Windows -if sys.platform.lower().startswith("win"): - - def get_winver(): - maj,min = sys.getwindowsversion()[0:2] - return '0x0%s' % ((maj * 100) + min) - - extensions = [Extension('_psutil_mswindows', - sources=['psutil/_psutil_mswindows.c', - 'psutil/_psutil_common.c', - 'psutil/arch/mswindows/process_info.c', - 'psutil/arch/mswindows/process_handles.c', - 'psutil/arch/mswindows/security.c'], - define_macros=[('_WIN32_WINNT', get_winver()), - ('_AVAIL_WINVER_', get_winver())], - libraries=["psapi", "kernel32", "advapi32", "shell32", - "netapi32"] - )] -# OS X -elif sys.platform.lower().startswith("darwin"): - extensions = [Extension('_psutil_osx', - sources = ['psutil/_psutil_osx.c', - 'psutil/_psutil_common.c', - 'psutil/arch/osx/process_info.c'], - extra_link_args=['-framework', 'CoreFoundation', '-framework', 'IOKit'] - ), - posix_extension] -# FreeBSD -elif sys.platform.lower().startswith("freebsd"): - extensions = [Extension('_psutil_bsd', - sources = ['psutil/_psutil_bsd.c', - 'psutil/_psutil_common.c', - 'psutil/arch/bsd/process_info.c'] - ), - posix_extension] -# Linux -elif sys.platform.lower().startswith("linux"): - extensions = [Extension('_psutil_linux', - sources=['psutil/_psutil_linux.c'], - ), - posix_extension] - -else: - raise NotImplementedError('platform %s is not supported' % sys.platform) - - -def main(): - setup_args = dict( - name='psutil', - version=__ver__, - download_url="http://psutil.googlecode.com/files/psutil-%s.tar.gz" % __ver__, - description='A process utilities module for Python', - long_description="""\ -psutil is a module providing convenience functions for monitoring -system and processes in a portable way by using Python.""", - keywords=['ps', 'top', 'kill', 'free', 'lsof', 'netstat', 'nice', - 'tty', 'ionice', 'uptime', 'taskmgr', 'process', 'df', - 'monitoring'], - author='Giampaolo Rodola, Jay Loden', - author_email='psutil@googlegroups.com', - url='http://code.google.com/p/psutil/', - platforms='Platform Independent', - license='License :: OSI Approved :: BSD License', - packages=['psutil'], - cmdclass={'build_py':build_py}, # Python 3.X - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows :: Windows NT/2000', - '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', - 'Topic :: System :: Monitoring', - 'Topic :: System :: Networking', - 'Topic :: System :: Benchmark', - 'Topic :: System :: Systems Administration', - 'Topic :: Utilities', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: MIT License', - ], - ) - if extensions is not None: - setup_args["ext_modules"] = extensions - - setup(**setup_args) - - -if __name__ == '__main__': - main() - diff --git a/third_party/psutil/test/_bsd.py b/third_party/psutil/test/_bsd.py deleted file mode 100644 index 0296b05..0000000 --- a/third_party/psutil/test/_bsd.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _bsd.py 1142 2011-10-05 18:45:49Z 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. - -"""BSD specific tests. These are implicitly run by test_psutil.py.""" - -import unittest -import subprocess -import time -import re -import sys - -import psutil - -from test_psutil import reap_children, get_test_subprocess, sh - -def sysctl(cmdline): - """Expects a sysctl command with an argument and parse the result - returning only the value of interest. - """ - result = sh("sysctl " + cmdline) - result = result[result.find(": ") + 2:] - try: - return int(result) - except ValueError: - return result - -def parse_sysctl_vmtotal(output): - """Parse sysctl vm.vmtotal output returning total and free memory - values. - """ - line = output.split('\n')[4] # our line of interest - mobj = re.match(r'Virtual\s+Memory.*Total:\s+(\d+)K,\s+Active\s+(\d+)K.*', line) - total, active = mobj.groups() - # values are represented in kilo bytes - total = int(total) * 1024 - active = int(active) * 1024 - free = total - active - return total, free - - -class BSDSpecificTestCase(unittest.TestCase): - - def setUp(self): - self.pid = get_test_subprocess().pid - - def tearDown(self): - reap_children() - - def test_TOTAL_PHYMEM(self): - sysctl_hwphymem = sysctl('sysctl hw.physmem') - self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM) - - 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) - - def test_avail_phymem(self): - # This test is not particularly accurate and may fail if the OS is - # consuming memory for other applications. - # We just want to test that the difference between psutil result - # and sysctl's is not too high. - _sum = sum((sysctl("sysctl vm.stats.vm.v_inactive_count"), - sysctl("sysctl vm.stats.vm.v_cache_count"), - sysctl("sysctl vm.stats.vm.v_free_count") - )) - _pagesize = sysctl("sysctl hw.pagesize") - sysctl_avail_phymem = _sum * _pagesize - psutil_avail_phymem = psutil.phymem_usage().free - difference = abs(psutil_avail_phymem - sysctl_avail_phymem) - # On my system both sysctl and psutil report the same values. - # Let's use a tollerance of 0.5 MB and consider the test as failed - # if we go over it. - if difference > (0.5 * 2**20): - self.fail("sysctl=%s; psutil=%s; difference=%s;" %( - sysctl_avail_phymem, psutil_avail_phymem, difference)) - - def test_total_virtmem(self): - # This test is not particularly accurate and may fail if the OS is - # consuming memory for other applications. - # We just want to test that the difference between psutil result - # and sysctl's is not too high. - p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE) - result = p.communicate()[0].strip() - if sys.version_info >= (3,): - result = str(result, sys.stdout.encoding) - sysctl_total_virtmem, _ = parse_sysctl_vmtotal(result) - psutil_total_virtmem = psutil.virtmem_usage().total - difference = abs(sysctl_total_virtmem - psutil_total_virtmem) - - # On my system I get a difference of 4657152 bytes, probably because - # the system is consuming memory for this same test. - # Assuming psutil is right, let's use a tollerance of 10 MB and consider - # the test as failed if we go over it. - if difference > (10 * 2**20): - self.fail("sysctl=%s; psutil=%s; difference=%s;" %( - sysctl_total_virtmem, psutil_total_virtmem, difference)) - - def test_avail_virtmem(self): - # This test is not particularly accurate and may fail if the OS is - # consuming memory for other applications. - # We just want to test that the difference between psutil result - # and sysctl's is not too high. - p = subprocess.Popen("sysctl vm.vmtotal", shell=1, stdout=subprocess.PIPE) - result = p.communicate()[0].strip() - if sys.version_info >= (3,): - result = str(result, sys.stdout.encoding) - _, sysctl_avail_virtmem = parse_sysctl_vmtotal(result) - psutil_avail_virtmem = psutil.virtmem_usage().free - difference = abs(sysctl_avail_virtmem - psutil_avail_virtmem) - # let's assume the test is failed if difference is > 0.5 MB - if difference > (0.5 * 2**20): - self.fail(difference) - - def test_process_create_time(self): - cmdline = "ps -o lstart -p %s" %self.pid - p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE) - output = p.communicate()[0] - if sys.version_info >= (3,): - output = str(output, sys.stdout.encoding) - start_ps = output.replace('STARTED', '').strip() - 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) - - def test_disks(self): - # test psutil.disk_usage() and psutil.disk_partitions() - # against "df -a" - def df(path): - out = sh('df -k "%s"' % path).strip() - lines = out.split('\n') - lines.pop(0) - line = lines.pop(0) - dev, total, used, free = line.split()[:4] - if dev == 'none': - dev = '' - total = int(total) * 1024 - used = int(used) * 1024 - free = int(free) * 1024 - return dev, total, used, free - - for part in psutil.disk_partitions(all=False): - usage = psutil.disk_usage(part.mountpoint) - dev, total, used, free = df(part.mountpoint) - self.assertEqual(part.device, dev) - self.assertEqual(usage.total, total) - # 10 MB tollerance - if abs(usage.free - free) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.free, free) - if abs(usage.used - used) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.used, used) - - -if __name__ == '__main__': - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(BSDSpecificTestCase)) - unittest.TextTestRunner(verbosity=2).run(test_suite) diff --git a/third_party/psutil/test/_linux.py b/third_party/psutil/test/_linux.py deleted file mode 100644 index a20d8dc..0000000 --- a/third_party/psutil/test/_linux.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _linux.py 1142 2011-10-05 18:45:49Z 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. - -"""Linux specific tests. These are implicitly run by test_psutil.py.""" - -import unittest -import subprocess -import sys - -from test_psutil import sh -import psutil - - -class LinuxSpecificTestCase(unittest.TestCase): - - def test_cached_phymem(self): - # test psutil.cached_phymem against "cached" column of free - # command line utility - p = subprocess.Popen("free", shell=1, stdout=subprocess.PIPE) - output = p.communicate()[0].strip() - if sys.version_info >= (3,): - output = str(output, sys.stdout.encoding) - free_cmem = int(output.split('\n')[1].split()[6]) - psutil_cmem = psutil.cached_phymem() / 1024 - self.assertEqual(free_cmem, psutil_cmem) - - def test_phymem_buffers(self): - # test psutil.phymem_buffers against "buffers" column of free - # command line utility - p = subprocess.Popen("free", shell=1, stdout=subprocess.PIPE) - output = p.communicate()[0].strip() - if sys.version_info >= (3,): - output = str(output, sys.stdout.encoding) - free_cmem = int(output.split('\n')[1].split()[5]) - psutil_cmem = psutil.phymem_buffers() / 1024 - self.assertEqual(free_cmem, psutil_cmem) - - def test_disks(self): - # test psutil.disk_usage() and psutil.disk_partitions() - # against "df -a" - def df(path): - out = sh('df -P -B 1 "%s"' % path).strip() - lines = out.split('\n') - lines.pop(0) - line = lines.pop(0) - dev, total, used, free = line.split()[:4] - if dev == 'none': - dev = '' - total, used, free = int(total), int(used), int(free) - return dev, total, used, free - - for part in psutil.disk_partitions(all=False): - usage = psutil.disk_usage(part.mountpoint) - dev, total, used, free = df(part.mountpoint) - self.assertEqual(part.device, dev) - self.assertEqual(usage.total, total) - # 10 MB tollerance - if abs(usage.free - free) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.free, free) - if abs(usage.used - used) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.used, used) - - -if __name__ == '__main__': - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(LinuxSpecificTestCase)) - unittest.TextTestRunner(verbosity=2).run(test_suite) diff --git a/third_party/psutil/test/_osx.py b/third_party/psutil/test/_osx.py deleted file mode 100644 index fdee67b..0000000 --- a/third_party/psutil/test/_osx.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _osx.py 1142 2011-10-05 18:45:49Z 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. - -"""OSX specific tests. These are implicitly run by test_psutil.py.""" - -import unittest -import subprocess -import time -import sys - -import psutil - -from test_psutil import reap_children, get_test_subprocess, sh -#from _posix import ps - - -def sysctl(cmdline): - """Expects a sysctl command with an argument and parse the result - returning only the value of interest. - """ - p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE) - result = p.communicate()[0].strip().split()[1] - if sys.version_info >= (3,): - result = str(result, sys.stdout.encoding) - try: - return int(result) - except ValueError: - return result - - -class OSXSpecificTestCase(unittest.TestCase): - - def setUp(self): - self.pid = get_test_subprocess().pid - - def tearDown(self): - reap_children() - - def test_TOTAL_PHYMEM(self): - sysctl_hwphymem = sysctl('sysctl hw.memsize') - self.assertEqual(sysctl_hwphymem, psutil.TOTAL_PHYMEM) - - def test_process_create_time(self): - cmdline = "ps -o lstart -p %s" %self.pid - p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE) - output = p.communicate()[0] - if sys.version_info >= (3,): - output = str(output, sys.stdout.encoding) - start_ps = output.replace('STARTED', '').strip() - 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) - - def test_disks(self): - # test psutil.disk_usage() and psutil.disk_partitions() - # against "df -a" - def df(path): - out = sh('df -k "%s"' % path).strip() - lines = out.split('\n') - lines.pop(0) - line = lines.pop(0) - dev, total, used, free = line.split()[:4] - if dev == 'none': - dev = '' - total = int(total) * 1024 - used = int(used) * 1024 - free = int(free) * 1024 - return dev, total, used, free - - for part in psutil.disk_partitions(all=False): - usage = psutil.disk_usage(part.mountpoint) - dev, total, used, free = df(part.mountpoint) - self.assertEqual(part.device, dev) - self.assertEqual(usage.total, total) - # 10 MB tollerance - if abs(usage.free - free) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.free, free) - if abs(usage.used - used) > 10 * 1024 * 1024: - self.fail("psutil=%s, df=%s" % usage.used, used) - - -if __name__ == '__main__': - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(OSXSpecificTestCase)) - unittest.TextTestRunner(verbosity=2).run(test_suite) diff --git a/third_party/psutil/test/_posix.py b/third_party/psutil/test/_posix.py deleted file mode 100644 index ad0db64..0000000 --- a/third_party/psutil/test/_posix.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _posix.py 1142 2011-10-05 18:45:49Z 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. - -"""POSIX specific tests. These are implicitly run by test_psutil.py.""" - -import unittest -import subprocess -import time -import sys -import os - -import psutil - -from test_psutil import (get_test_subprocess, reap_children, PYTHON, LINUX, OSX, - ignore_access_denied, sh) - - -def ps(cmd): - """Expects a ps command with a -o argument and parse the result - returning only the value of interest. - """ - if not LINUX: - cmd = cmd.replace(" --no-headers ", " ") - p = subprocess.Popen(cmd, shell=1, stdout=subprocess.PIPE) - output = p.communicate()[0].strip() - if sys.version_info >= (3,): - output = str(output, sys.stdout.encoding) - if not LINUX: - output = output.split('\n')[1] - try: - return int(output) - except ValueError: - return output - - -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"]).pid - - def tearDown(self): - reap_children() - - 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 - self.assertEqual(ppid_ps, ppid_psutil) - - def test_process_uid(self): - uid_ps = ps("ps --no-headers -o uid -p %s" %self.pid) - uid_psutil = psutil.Process(self.pid).uids.real - self.assertEqual(uid_ps, uid_psutil) - - def test_process_gid(self): - gid_ps = ps("ps --no-headers -o rgid -p %s" %self.pid) - gid_psutil = psutil.Process(self.pid).gids.real - 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 - self.assertEqual(username_ps, username_psutil) - - @ignore_access_denied - 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 - self.assertEqual(rss_ps, rss_psutil) - - @ignore_access_denied - 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 - 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] - # 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) - - 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 - try: - self.assertEqual(ps_pathname, psutil_pathname) - except AssertionError: - # certain platforms such as BSD are more accurate returning: - # "/usr/local/bin/python2.7" - # ...instead of: - # "/usr/local/bin/python" - # We do not want to consider this difference in accuracy - # an error. - adjusted_ps_pathname = ps_pathname[:len(ps_pathname)] - 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) - self.assertEqual(ps_cmdline, psutil_cmdline) - - def test_get_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) - output = p.communicate()[0].strip() - if sys.version_info >= (3,): - 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())) - # remove ps subprocess pid which is supposed to be dead in meantime - pids_ps.remove(p.pid) - pids_psutil = psutil.get_pid_list() - pids_ps.sort() - pids_psutil.sort() - - if pids_ps != pids_psutil: - difference = [x for x in pids_psutil if x not in pids_ps] + \ - [x for x in pids_ps if x not in pids_psutil] - self.fail("difference: " + str(difference)) - - -if __name__ == '__main__': - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(PosixSpecificTestCase)) - unittest.TextTestRunner(verbosity=2).run(test_suite) - - diff --git a/third_party/psutil/test/_windows.py b/third_party/psutil/test/_windows.py deleted file mode 100644 index ef5ff24..0000000 --- a/third_party/psutil/test/_windows.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python -# -# $Id: _windows.py 1142 2011-10-05 18:45:49Z 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. - -"""Windows specific tests. These are implicitly run by test_psutil.py.""" - -import os -import unittest -import platform -import signal -import time -import warnings -import atexit -import sys - -import psutil -import _psutil_mswindows -from test_psutil import reap_children, get_test_subprocess, wait_for_pid -try: - import wmi -except ImportError: - err = sys.exc_info()[1] - atexit.register(warnings.warn, "Couldn't run wmi tests: %s" % str(err), - RuntimeWarning) - wmi = None - -WIN2000 = platform.win32_ver()[0] == '2000' - - -class WindowsSpecificTestCase(unittest.TestCase): - - def setUp(self): - sproc = get_test_subprocess() - wait_for_pid(sproc.pid) - self.pid = sproc.pid - - def tearDown(self): - reap_children() - - def test_issue_24(self): - p = psutil.Process(0) - self.assertRaises(psutil.AccessDenied, p.kill) - - def test_special_pid(self): - if not WIN2000: - p = psutil.Process(4) - else: - p = psutil.Process(8) - self.assertEqual(p.name, 'System') - # use __str__ to access all common Process properties to check - # that nothing strange happens - str(p) - p.username - self.assertTrue(p.create_time >= 0.0) - try: - rss, vms = p.get_memory_info() - except psutil.AccessDenied: - # expected on Windows Vista and Windows 7 - if not platform.uname()[1] in ('vista', 'win-7', 'win7'): - raise - else: - self.assertTrue(rss > 0) - if not WIN2000: - self.assertEqual(vms, 0) - - def test_signal(self): - p = psutil.Process(self.pid) - self.assertRaises(ValueError, p.send_signal, signal.SIGINT) - - if wmi is not None: - - # --- Process class tests - - def test_process_name(self): - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - self.assertEqual(p.name, w.Caption) - - def test_process_exe(self): - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - self.assertEqual(p.exe, w.ExecutablePath) - - if not WIN2000: - def test_process_cmdline(self): - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - self.assertEqual(' '.join(p.cmdline), w.CommandLine.replace('"', '')) - - def test_process_username(self): - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - domain, _, username = w.GetOwner() - username = "%s\\%s" %(domain, username) - self.assertEqual(p.username, username) - - def test_process_rss_memory(self): - time.sleep(0.1) - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - rss = p.get_memory_info().rss - self.assertEqual(rss, int(w.WorkingSetSize)) - - def test_process_vms_memory(self): - time.sleep(0.1) - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - vms = p.get_memory_info().vms - # http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx - # ...claims that PageFileUsage is represented in Kilo - # bytes but funnily enough on certain platforms bytes are - # returned instead. - wmi_usage = int(w.PageFileUsage) - if (vms != wmi_usage) and (vms != wmi_usage * 1024): - self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms)) - - def test_process_create_time(self): - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(self.pid) - wmic_create = str(w.CreationDate.split('.')[0]) - psutil_create = time.strftime("%Y%m%d%H%M%S", - time.localtime(p.create_time)) - self.assertEqual(wmic_create, psutil_create) - - - # --- psutil namespace functions and constants tests - - def test_NUM_CPUS(self): - num_cpus = int(os.environ['NUMBER_OF_PROCESSORS']) - self.assertEqual(num_cpus, psutil.NUM_CPUS) - - def test_TOTAL_PHYMEM(self): - w = wmi.WMI().Win32_ComputerSystem()[0] - self.assertEqual(int(w.TotalPhysicalMemory), psutil.TOTAL_PHYMEM) - - def test__UPTIME(self): - # _UPTIME constant is not public but it is used internally - # as value to return for pid 0 creation time. - # WMI behaves the same. - w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0] - p = psutil.Process(0) - wmic_create = str(w.CreationDate.split('.')[0]) - psutil_create = time.strftime("%Y%m%d%H%M%S", - time.localtime(p.create_time)) - # XXX - ? no actual test here - - def test_get_pids(self): - # Note: this test might fail if the OS is starting/killing - # other processes in the meantime - w = wmi.WMI().Win32_Process() - wmi_pids = [x.ProcessId for x in w] - wmi_pids.sort() - psutil_pids = psutil.get_pid_list() - psutil_pids.sort() - if wmi_pids != psutil_pids: - difference = filter(lambda x:x not in wmi_pids, psutil_pids) + \ - filter(lambda x:x not in psutil_pids, wmi_pids) - self.fail("difference: " + str(difference)) - - def test_disks(self): - ps_parts = psutil.disk_partitions(all=True) - wmi_parts = wmi.WMI().Win32_LogicalDisk() - for ps_part in ps_parts: - for wmi_part in wmi_parts: - if ps_part.device.replace('\\', '') == wmi_part.DeviceID: - if not ps_part.mountpoint: - # this is usually a CD-ROM with no disk inserted - break - usage = psutil.disk_usage(ps_part.mountpoint) - self.assertEqual(usage.total, int(wmi_part.Size)) - wmi_free = int(wmi_part.FreeSpace) - self.assertEqual(usage.free, wmi_free) - # 10 MB tollerance - if abs(usage.free - wmi_free) > 10 * 1024 * 1024: - self.fail("psutil=%s, wmi=%s" % usage.free, wmi_free) - break - else: - self.fail("can't find partition %r", ps_part) - - -if __name__ == '__main__': - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(WindowsSpecificTestCase)) - unittest.TextTestRunner(verbosity=2).run(test_suite) - diff --git a/third_party/psutil/test/test_memory_leaks.py b/third_party/psutil/test/test_memory_leaks.py deleted file mode 100644 index b6a3a4e..0000000 --- a/third_party/psutil/test/test_memory_leaks.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python -# -# $Id: test_memory_leaks.py 1142 2011-10-05 18:45:49Z 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. - -""" -A test script which attempts to detect memory leaks by calling C -functions many times and compare process memory usage before and -after the calls. It might produce false positives. -""" - -import os -import gc -import unittest -import time - -import psutil -from test_psutil import reap_children, skipUnless, skipIf, \ - POSIX, LINUX, WINDOWS, OSX, BSD, PY3 - -LOOPS = 1000 -TOLERANCE = 4096 - -if PY3: - xrange = range - - -class Base(unittest.TestCase): - - def execute(self, function, *args, **kwargs): - # step 1 - for x in xrange(LOOPS): - self.call(function, *args, **kwargs) - del x - gc.collect() - rss1 = self.get_mem() - - # step 2 - for x in xrange(LOOPS): - self.call(function, *args, **kwargs) - del x - gc.collect() - rss2 = self.get_mem() - - # comparison - difference = rss2 - rss1 - if difference > TOLERANCE: - # This doesn't necessarily mean we have a leak yet. - # At this point we assume that after having called the - # function so many times the memory usage is stabilized - # and if there are no leaks it should not increase any - # more. - # Let's keep calling fun for 3 more seconds and fail if - # we notice any difference. - stop_at = time.time() + 3 - while 1: - self.call(function, *args, **kwargs) - if time.time() >= stop_at: - break - del stop_at - gc.collect() - rss3 = self.get_mem() - difference = rss3 - rss2 - if rss3 > rss2: - self.fail("rss2=%s, rss3=%s, difference=%s" \ - % (rss2, rss3, difference)) - - @staticmethod - def get_mem(): - return psutil.Process(os.getpid()).get_memory_info()[0] - - def call(self): - raise NotImplementedError("must be implemented in subclass") - - -class TestProcessObjectLeaks(Base): - """Test leaks of Process class methods and properties""" - - def setUp(self): - gc.collect() - - def tearDown(self): - reap_children() - - def call(self, function, *args, **kwargs): - p = psutil.Process(os.getpid()) - obj = getattr(p, function) - if callable(obj): - obj(*args, **kwargs) - - def test_name(self): - self.execute('name') - - def test_cmdline(self): - self.execute('cmdline') - - def test_ppid(self): - self.execute('ppid') - - @skipIf(WINDOWS) - def test_uids(self): - self.execute('uids') - - @skipIf(WINDOWS) - def test_gids(self): - self.execute('gids') - - def test_status(self): - self.execute('status') - - @skipIf(POSIX) - def test_username(self): - self.execute('username') - - def test_create_time(self): - self.execute('create_time') - - def test_get_num_threads(self): - self.execute('get_num_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') - - def test_is_running(self): - self.execute('is_running') - - @skipIf(WINDOWS) - def test_terminal(self): - self.execute('terminal') - - @skipUnless(WINDOWS) - def test_resume(self): - self.execute('resume') - - @skipUnless(WINDOWS) - def test_getcwd(self): - self.execute('getcwd') - - @skipUnless(WINDOWS or OSX) - def test_get_open_files(self): - self.execute('get_open_files') - - @skipUnless(WINDOWS or OSX) - def test_get_connections(self): - self.execute('get_connections') - - -class TestModuleFunctionsLeaks(Base): - """Test leaks of psutil module functions.""" - - def setUp(self): - gc.collect() - - def call(self, function, *args, **kwargs): - obj = getattr(psutil, function) - if callable(obj): - retvalue = obj(*args, **kwargs) - - def test_get_pid_list(self): - self.execute('get_pid_list') - - @skipIf(POSIX) - def test_pid_exists(self): - self.execute('pid_exists', os.getpid()) - - def test_process_iter(self): - self.execute('process_iter') - - def test_phymem_usage(self): - self.execute('phymem_usage') - - def test_virtmem_usage(self): - self.execute('virtmem_usage') - - def test_cpu_times(self): - self.execute('cpu_times') - - def test_per_cpu_times(self): - self.execute('cpu_times', percpu=True) - - @skipUnless(WINDOWS) - 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') - - def test_disk_io_counters(self): - self.execute('disk_io_counters') - -def test_main(): - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestProcessObjectLeaks)) - test_suite.addTest(unittest.makeSuite(TestModuleFunctionsLeaks)) - unittest.TextTestRunner(verbosity=2).run(test_suite) - -if __name__ == '__main__': - test_main() - diff --git a/third_party/psutil/test/test_psutil.py b/third_party/psutil/test/test_psutil.py deleted file mode 100644 index 35ed744..0000000 --- a/third_party/psutil/test/test_psutil.py +++ /dev/null @@ -1,1493 +0,0 @@ -#!/usr/bin/env python -# -# $Id: test_psutil.py 1142 2011-10-05 18:45:49Z 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. - -""" -psutil test suite. - -Note: this is targeted for both python 2.x and 3.x so there's no need -to use 2to3 tool first. -""" - -import unittest -import os -import sys -import subprocess -import time -import signal -import types -import traceback -import socket -import warnings -import atexit -import errno -import threading -import tempfile -import collections - -import psutil - - -PYTHON = os.path.realpath(sys.executable) -DEVNULL = open(os.devnull, 'r+') -TESTFN = os.path.join(os.getcwd(), "$testfile") -PY3 = sys.version_info >= (3,) -POSIX = os.name == 'posix' -LINUX = sys.platform.lower().startswith("linux") -WINDOWS = sys.platform.lower().startswith("win32") -OSX = sys.platform.lower().startswith("darwin") -BSD = sys.platform.lower().startswith("freebsd") - -try: - psutil.Process(os.getpid()).get_connections() -except NotImplementedError: - err = sys.exc_info()[1] - SUPPORT_CONNECTIONS = False - atexit.register(warnings.warn, "get_connections() not supported on this platform", - RuntimeWarning) -else: - SUPPORT_CONNECTIONS = True - -if PY3: - long = int - - def callable(attr): - return isinstance(attr, collections.Callable) - - -_subprocesses_started = set() - -def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL, stdin=None): - """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. - """ - if cmd is None: - cmd = [PYTHON, "-c", "import time; time.sleep(3600);"] - sproc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr, stdin=stdin) - _subprocesses_started.add(sproc.pid) - return sproc - -def sh(cmdline): - """run cmd in a subprocess and return its output. - raises RuntimeError on error. - """ - p = subprocess.Popen(cmdline, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - raise RuntimeError(stderr) - if stderr: - warnings.warn(stderr, RuntimeWarning) - if sys.version_info >= (3,): - stdout = str(stdout, sys.stdout.encoding) - return stdout.strip() - -def wait_for_pid(pid, timeout=1): - """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(): - # give it one more iteration to allow full initialization - time.sleep(0.01) - return - time.sleep(0.0001) - if time.time() >= raise_at: - raise RuntimeError("Timed out") - -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. - """ - if search_all: - this_process = psutil.Process(os.getpid()) - pids = [x.pid for x in this_process.get_children()] - else: - pids =_subprocesses_started - while pids: - pid = pids.pop() - try: - child = psutil.Process(pid) - child.kill() - except psutil.NoSuchProcess: - pass - else: - child.wait() - - -# we want to search through all processes before exiting -atexit.register(reap_children, search_all=True) - -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 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(warnings.warn, msg, RuntimeWarning) - 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 ignore_access_denied(fun): - """Decorator to Ignore AccessDenied exceptions.""" - def outer(fun, *args, **kwargs): - def inner(self): - try: - return fun(self, *args, **kwargs) - except psutil.AccessDenied: - pass - return inner - return outer - -def supports_ipv6(): - """Return True if IPv6 is supported on this platform.""" - if not socket.has_ipv6 or not hasattr(socket, "AF_INET6"): - return False - sock = None - try: - try: - sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) - sock.bind(("::1", 0)) - except (socket.error, socket.gaierror): - return False - else: - return True - finally: - if sock is not None: - sock.close() - - -class ThreadTask(threading.Thread): - """A thread object used for running process thread tests.""" - - def __init__(self): - threading.Thread.__init__(self) - self._running = False - self._interval = None - self._flag = threading.Event() - - def __repr__(self): - name = self.__class__.__name__ - return '<%s running=%s at %#x>' % (name, self._running, id(self)) - - def start(self, interval=0.001): - """Start thread and keep it running until an explicit - stop() request. Polls for shutdown every 'timeout' seconds. - """ - if self._running: - raise ValueError("already started") - self._interval = interval - threading.Thread.start(self) - self._flag.wait() - - def run(self): - self._running = True - self._flag.set() - while self._running: - time.sleep(self._interval) - - def stop(self): - """Stop thread execution and and waits until it is stopped.""" - if not self._running: - raise ValueError("already stopped") - self._running = False - self.join() - - -class TestCase(unittest.TestCase): - - def tearDown(self): - reap_children() - - # ============================ - # tests for system-related API - # ============================ - - def test_get_process_list(self): - pids = [x.pid for x in psutil.get_process_list()] - self.assertTrue(os.getpid() in pids) - - def test_process_iter(self): - pids = [x.pid for x in psutil.process_iter()] - self.assertTrue(os.getpid() in pids) - - def test_TOTAL_PHYMEM(self): - x = psutil.TOTAL_PHYMEM - self.assertTrue(isinstance(x, (int, long))) - self.assertTrue(x > 0) - - def test_BOOT_TIME(self): - x = psutil.BOOT_TIME - self.assertTrue(isinstance(x, float)) - self.assertTrue(x > 0) - - def test_deprecated_memory_functions(self): - warnings.filterwarnings("error") - try: - 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) - finally: - warnings.resetwarnings() - - def test_phymem_usage(self): - mem = psutil.phymem_usage() - self.assertTrue(mem.total > 0) - self.assertTrue(mem.used > 0) - self.assertTrue(mem.free > 0) - self.assertTrue(0 <= mem.percent <= 100) - - def test_virtmem_usage(self): - mem = psutil.virtmem_usage() - self.assertTrue(mem.total > 0) - self.assertTrue(mem.used >= 0) - self.assertTrue(mem.free > 0) - self.assertTrue(0 <= mem.percent <= 100) - - @skipUnless(LINUX) - def test_phymem_buffers(self): - x = psutil.phymem_buffers() - self.assertTrue(isinstance(x, (int, long))) - self.assertTrue(x >= 0) - - def test_pid_exists(self): - sproc = get_test_subprocess() - wait_for_pid(sproc.pid) - self.assertTrue(psutil.pid_exists(sproc.pid)) - p = psutil.Process(sproc.pid) - p.kill() - p.wait() - self.assertFalse(psutil.pid_exists(sproc.pid)) - self.assertFalse(psutil.pid_exists(-1)) - - def test_pid_exists_2(self): - reap_children() - pids = psutil.get_pid_list() - for pid in pids: - try: - self.assertTrue(psutil.pid_exists(pid)) - except AssertionError: - # in case the process disappeared in meantime fail only - # if it is no longer in get_pid_list() - time.sleep(.1) - if pid in psutil.get_pid_list(): - self.fail(pid) - pids = range(max(pids) + 5000, max(pids) + 6000) - for pid in pids: - self.assertFalse(psutil.pid_exists(pid)) - - def test_get_pid_list(self): - plist = [x.pid for x in psutil.get_process_list()] - pidlist = psutil.get_pid_list() - self.assertEqual(plist.sort(), pidlist.sort()) - # make sure every pid is unique - self.assertEqual(len(pidlist), len(set(pidlist))) - - def test_test(self): - # test for psutil.test() function - stdout = sys.stdout - sys.stdout = DEVNULL - try: - psutil.test() - finally: - sys.stdout = stdout - - def test_sys_cpu_times(self): - total = 0 - times = psutil.cpu_times() - sum(times) - for cp_time in times: - self.assertTrue(isinstance(cp_time, float)) - self.assertTrue(cp_time >= 0.0) - total += cp_time - self.assertEqual(total, sum(times)) - str(times) - - def test_sys_cpu_times2(self): - t1 = sum(psutil.cpu_times()) - time.sleep(0.1) - t2 = sum(psutil.cpu_times()) - difference = t2 - t1 - if not difference >= 0.05: - self.fail("difference %s" % difference) - - def test_sys_per_cpu_times(self): - for times in psutil.cpu_times(percpu=True): - total = 0 - sum(times) - for cp_time in times: - self.assertTrue(isinstance(cp_time, float)) - self.assertTrue(cp_time >= 0.0) - total += cp_time - self.assertEqual(total, sum(times)) - str(times) - - def test_sys_per_cpu_times2(self): - tot1 = psutil.cpu_times(percpu=True) - stop_at = time.time() + 0.1 - while 1: - if time.time() >= stop_at: - break - tot2 = psutil.cpu_times(percpu=True) - for t1, t2 in zip(tot1, tot2): - t1, t2 = sum(t1), sum(t2) - difference = t2 - t1 - if difference >= 0.05: - return - self.fail() - - def test_sys_cpu_percent(self): - psutil.cpu_percent(interval=0.001) - psutil.cpu_percent(interval=0.001) - for x in range(1000): - percent = psutil.cpu_percent(interval=None) - self.assertTrue(isinstance(percent, float)) - self.assertTrue(percent >= 0.0) - self.assertTrue(percent <= 100.0) - - def test_sys_per_cpu_percent(self): - psutil.cpu_percent(interval=0.001, percpu=True) - psutil.cpu_percent(interval=0.001, percpu=True) - for x in range(1000): - percents = psutil.cpu_percent(interval=None, percpu=True) - for percent in percents: - self.assertTrue(isinstance(percent, float)) - self.assertTrue(percent >= 0.0) - self.assertTrue(percent <= 100.0) - - def test_sys_cpu_percent_compare(self): - psutil.cpu_percent(interval=0) - psutil.cpu_percent(interval=0, percpu=True) - time.sleep(.1) - t1 = psutil.cpu_percent(interval=0) - t2 = psutil.cpu_percent(interval=0, percpu=True) - # calculate total average - t2 = sum(t2) / len(t2) - if abs(t1 - t2) > 5: - self.assertEqual(t1, t2) - - def test_disk_usage(self): - usage = psutil.disk_usage(os.getcwd()) - self.assertTrue(usage.total > 0) - self.assertTrue(usage.used > 0) - self.assertTrue(usage.free > 0) - self.assertTrue(usage.total > usage.used) - self.assertTrue(usage.total > usage.free) - self.assertTrue(0 <= usage.percent <= 100) - - # 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] - if err.args[0] != errno.ENOENT: - raise - else: - self.fail("OSError not raised") - - def test_disk_partitions(self): - for disk in psutil.disk_partitions(all=False): - self.assertTrue(os.path.exists(disk.device)) - self.assertTrue(os.path.isdir(disk.mountpoint)) - self.assertTrue(disk.fstype) - for disk in psutil.disk_partitions(all=True): - if not WINDOWS: - self.assertTrue(os.path.isdir(disk.mountpoint)) - self.assertTrue(disk.fstype) - - def find_mount_point(path): - path = os.path.abspath(path) - while not os.path.ismount(path): - path = os.path.dirname(path) - return path - - mount = find_mount_point(__file__) - mounts = [x.mountpoint for x in psutil.disk_partitions(all=True)] - self.assertTrue(mount in mounts) - psutil.disk_usage(mount) - - # XXX - @skipUnless(hasattr(psutil, "network_io_counters")) - def test_anetwork_io_counters(self): - def check_ntuple(nt): - self.assertEqual(nt[0], nt.bytes_sent) - self.assertEqual(nt[1], nt.bytes_recv) - self.assertEqual(nt[2], nt.packets_sent) - self.assertEqual(nt[3], nt.packets_recv) - self.assertTrue(nt.bytes_sent >= 0) - self.assertTrue(nt.bytes_recv >= 0) - self.assertTrue(nt.packets_sent >= 0) - self.assertTrue(nt.packets_recv >= 0) - - ret = psutil.network_io_counters(pernic=False) - check_ntuple(ret) - ret = psutil.network_io_counters(pernic=True) - for name, ntuple in ret.iteritems(): - self.assertTrue(name) - check_ntuple(ntuple) - # XXX - @skipUnless(hasattr(psutil, "disk_io_counters")) - def test_disk_io_counters(self): - def check_ntuple(nt): - self.assertEqual(nt[0], nt.read_count) - self.assertEqual(nt[1], nt.write_count) - self.assertEqual(nt[2], nt.read_bytes) - self.assertEqual(nt[3], nt.write_bytes) - self.assertEqual(nt[4], nt.read_time) - self.assertEqual(nt[5], nt.write_time) - self.assertTrue(nt.read_count >= 0) - self.assertTrue(nt.write_count >= 0) - self.assertTrue(nt.read_bytes >= 0) - self.assertTrue(nt.write_bytes >= 0) - self.assertTrue(nt.read_time >= 0) - self.assertTrue(nt.write_time >= 0) - - ret = psutil.disk_io_counters(perdisk=False) - check_ntuple(ret) - ret = psutil.disk_io_counters(perdisk=True) - for name, ntuple in ret.iteritems(): - self.assertTrue(name) - check_ntuple(ntuple) - - # ==================== - # Process object tests - # ==================== - - def test_kill(self): - sproc = get_test_subprocess() - test_pid = sproc.pid - wait_for_pid(test_pid) - p = psutil.Process(test_pid) - name = p.name - p.kill() - p.wait() - self.assertFalse(psutil.pid_exists(test_pid) and name == PYTHON) - - def test_terminate(self): - sproc = get_test_subprocess() - test_pid = sproc.pid - wait_for_pid(test_pid) - p = psutil.Process(test_pid) - name = p.name - p.terminate() - p.wait() - self.assertFalse(psutil.pid_exists(test_pid) and name == PYTHON) - - def test_send_signal(self): - if POSIX: - sig = signal.SIGKILL - else: - sig = 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) - - def test_wait(self): - # check exit code signal - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.kill() - code = p.wait() - if os.name == 'posix': - self.assertEqual(code, signal.SIGKILL) - else: - self.assertEqual(code, 0) - self.assertFalse(p.is_running()) - - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.terminate() - code = p.wait() - if os.name == 'posix': - self.assertEqual(code, signal.SIGTERM) - else: - self.assertEqual(code, 0) - self.assertFalse(p.is_running()) - - # check sys.exit() code - code = "import time, sys; time.sleep(0.01); sys.exit(5);" - sproc = get_test_subprocess([PYTHON, "-c", code]) - p = psutil.Process(sproc.pid) - self.assertEqual(p.wait(), 5) - self.assertFalse(p.is_running()) - - # Test wait() issued twice. - # It is not supposed to raise NSP when the process is gone. - # On UNIX this should return None, on Windows it should keep - # returning the exit code. - sproc = get_test_subprocess([PYTHON, "-c", code]) - p = psutil.Process(sproc.pid) - self.assertEqual(p.wait(), 5) - self.assertTrue(p.wait() in (5, None)) - - # test timeout - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.name - self.assertRaises(psutil.TimeoutExpired, p.wait, 0.01) - - # timeout < 0 not allowed - self.assertRaises(ValueError, p.wait, -1) - - @skipUnless(POSIX) - 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 += "sp = Popen(cmd, stdout=PIPE);" - code += "sys.stdout.write(str(sp.pid));" - sproc = get_test_subprocess([PYTHON, "-c", code], stdout=subprocess.PIPE) - - grandson_pid = int(sproc.stdout.read()) - grandson_proc = psutil.Process(grandson_pid) - try: - self.assertRaises(psutil.TimeoutExpired, grandson_proc.wait, 0.01) - grandson_proc.kill() - ret = grandson_proc.wait() - self.assertEqual(ret, None) - finally: - if grandson_proc.is_running(): - grandson_proc.kill() - grandson_proc.wait() - - def test_wait_timeout_0(self): - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - self.assertRaises(psutil.TimeoutExpired, p.wait, 0) - p.kill() - stop_at = time.time() + 2 - while 1: - try: - code = p.wait(0) - except psutil.TimeoutExpired: - if time.time() >= stop_at: - raise - else: - break - if os.name == 'posix': - self.assertEqual(code, signal.SIGKILL) - else: - self.assertEqual(code, 0) - self.assertFalse(p.is_running()) - - def test_cpu_percent(self): - p = psutil.Process(os.getpid()) - p.get_cpu_percent(interval=0.001) - p.get_cpu_percent(interval=0.001) - for x in range(100): - percent = p.get_cpu_percent(interval=None) - self.assertTrue(isinstance(percent, float)) - self.assertTrue(percent >= 0.0) - self.assertTrue(percent <= 100.0) - - def test_cpu_times(self): - times = psutil.Process(os.getpid()).get_cpu_times() - self.assertTrue((times.user > 0.0) or (times.system > 0.0)) - # make sure returned values can be pretty printed with strftime - time.strftime("%H:%M:%S", time.localtime(times.user)) - time.strftime("%H:%M:%S", time.localtime(times.system)) - - # Test Process.cpu_times() against os.times() - # os.times() is broken on Python 2.6 - # http://bugs.python.org/issue1040026 - # 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) - def test_cpu_times2(self): - user_time, kernel_time = psutil.Process(os.getpid()).get_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)) - - if (max([kernel_time, ktime]) - min([kernel_time, ktime])) > 0.1: - self.fail("expected: %s, found: %s" %(ktime, kernel_time)) - - def test_create_time(self): - sproc = get_test_subprocess() - now = time.time() - wait_for_pid(sproc.pid) - p = psutil.Process(sproc.pid) - create_time = p.create_time - - # Use time.time() as base value to compare our result using a - # tolerance of +/- 1 second. - # It will fail if the difference between the values is > 2s. - difference = abs(create_time - now) - if difference > 2: - self.fail("expected: %s, found: %s, difference: %s" - % (now, create_time, difference)) - - # make sure returned value can be pretty printed with strftime - time.strftime("%Y %m %d %H:%M:%S", time.localtime(p.create_time)) - - @skipIf(WINDOWS) - 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()) - # test reads - io1 = p.get_io_counters() - f = open(PYTHON, 'rb') - f.read() - f.close() - io2 = p.get_io_counters() - if not BSD: - self.assertTrue(io2.read_count > io1.read_count) - self.assertTrue(io2.write_count == io1.write_count) - self.assertTrue(io2.read_bytes >= io1.read_bytes) - self.assertTrue(io2.write_bytes >= io1.write_bytes) - # test writes - io1 = p.get_io_counters() - f = tempfile.TemporaryFile() - if sys.version_info >= (3,): - f.write(bytes("x" * 1000000, 'ascii')) - else: - f.write("x" * 1000000) - f.close() - io2 = p.get_io_counters() - if not BSD: - self.assertTrue(io2.write_count > io1.write_count) - self.assertTrue(io2.write_bytes > io1.write_bytes) - self.assertTrue(io2.read_count >= io1.read_count) - self.assertTrue(io2.read_bytes >= io1.read_bytes) - - @skipUnless(LINUX) - def test_get_set_ionice(self): - from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, - IOPRIO_CLASS_IDLE) - self.assertEqual(IOPRIO_CLASS_NONE, 0) - self.assertEqual(IOPRIO_CLASS_RT, 1) - self.assertEqual(IOPRIO_CLASS_BE, 2) - self.assertEqual(IOPRIO_CLASS_IDLE, 3) - p = psutil.Process(os.getpid()) - try: - p.set_ionice(2) - ioclass, value = p.get_ionice() - self.assertEqual(ioclass, 2) - self.assertEqual(value, 4) - # - p.set_ionice(3) - ioclass, value = p.get_ionice() - self.assertEqual(ioclass, 3) - self.assertEqual(value, 0) - # - p.set_ionice(2, 0) - ioclass, value = p.get_ionice() - self.assertEqual(ioclass, 2) - self.assertEqual(value, 0) - p.set_ionice(2, 7) - ioclass, value = p.get_ionice() - self.assertEqual(ioclass, 2) - self.assertEqual(value, 7) - self.assertRaises(ValueError, p.set_ionice, 2, 10) - finally: - p.set_ionice(IOPRIO_CLASS_NONE) - - def test_get_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() - - thread = ThreadTask() - thread.start() - try: - step2 = p.get_num_threads() - self.assertEqual(step2, step1 + 1) - thread.stop() - finally: - if thread._running: - thread.stop() - - def test_get_threads(self): - p = psutil.Process(os.getpid()) - step1 = p.get_threads() - - thread = ThreadTask() - thread.start() - - try: - step2 = p.get_threads() - self.assertEqual(len(step2), len(step1) + 1) - # on Linux, first thread id is supposed to be this process - if LINUX: - self.assertEqual(step2[0].id, os.getpid()) - athread = step2[0] - # test named tuple - self.assertEqual(athread.id, athread[0]) - self.assertEqual(athread.user_time, athread[1]) - self.assertEqual(athread.system_time, athread[2]) - # test num threads - thread.stop() - finally: - if thread._running: - thread.stop() - - def test_get_memory_info(self): - p = psutil.Process(os.getpid()) - - # step 1 - get a base value to compare our results - rss1, vms1 = p.get_memory_info() - percent1 = p.get_memory_percent() - self.assertTrue(rss1 > 0) - self.assertTrue(vms1 > 0) - - # step 2 - allocate some memory - memarr = [None] * 1500000 - - rss2, vms2 = p.get_memory_info() - percent2 = p.get_memory_percent() - # make sure that the memory usage bumped up - self.assertTrue(rss2 > rss1) - self.assertTrue(vms2 >= vms1) # vms might be equal - self.assertTrue(percent2 > percent1) - del memarr - - def test_get_memory_percent(self): - p = psutil.Process(os.getpid()) - self.assertTrue(p.get_memory_percent() > 0.0) - - def test_pid(self): - sproc = get_test_subprocess() - self.assertEqual(psutil.Process(sproc.pid).pid, sproc.pid) - - def test_is_running(self): - sproc = get_test_subprocess() - wait_for_pid(sproc.pid) - p = psutil.Process(sproc.pid) - self.assertTrue(p.is_running()) - p.kill() - p.wait() - self.assertFalse(p.is_running()) - - def test_exe(self): - sproc = get_test_subprocess() - wait_for_pid(sproc.pid) - try: - self.assertEqual(psutil.Process(sproc.pid).exe, PYTHON) - except AssertionError: - # certain platforms such as BSD are more accurate returning: - # "/usr/local/bin/python2.7" - # ...instead of: - # "/usr/local/bin/python" - # We do not want to consider this difference in accuracy - # an error. - name = psutil.Process(sproc.pid).exe - adjusted_name = PYTHON[:len(name)] - self.assertEqual(name, adjusted_name) - for p in psutil.process_iter(): - try: - exe = p.exe - except psutil.Error: - continue - if not exe: - continue - if not os.path.exists(exe): - self.fail("%s does not exist (pid=%s, name=%s, cmdline=%s)" \ - % (repr(exe), p.pid, p.name, p.cmdline)) - if hasattr(os, 'access') and hasattr(os, "X_OK"): - if not os.access(p.exe, os.X_OK): - self.fail("%s is not executable (pid=%s, name=%s, cmdline=%s)" \ - % (repr(p.exe), p.pid, p.name, p.cmdline)) - - def test_cmdline(self): - sproc = get_test_subprocess([PYTHON, "-E"]) - wait_for_pid(sproc.pid) - self.assertEqual(psutil.Process(sproc.pid).cmdline, [PYTHON, "-E"]) - - def test_name(self): - sproc = get_test_subprocess(PYTHON) - wait_for_pid(sproc.pid) - self.assertEqual(psutil.Process(sproc.pid).name.lower(), - os.path.basename(sys.executable).lower()) - - 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, setattr, p, "nice", "str") - try: - 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: - # going back to previous nice value raises AccessDenied on OSX - if not OSX: - p.nice = first_nice - - if os.name == 'nt': - - def test_nice(self): - p = psutil.Process(os.getpid()) - self.assertRaises(TypeError, setattr, p, "nice", "str") - try: - self.assertEqual(p.nice, psutil.NORMAL_PRIORITY_CLASS) - p.nice = psutil.HIGH_PRIORITY_CLASS - self.assertEqual(p.nice, psutil.HIGH_PRIORITY_CLASS) - p.nice = psutil.NORMAL_PRIORITY_CLASS - self.assertEqual(p.nice, psutil.NORMAL_PRIORITY_CLASS) - finally: - p.nice = psutil.NORMAL_PRIORITY_CLASS - - def test_status(self): - p = psutil.Process(os.getpid()) - self.assertEqual(p.status, psutil.STATUS_RUNNING) - self.assertEqual(str(p.status), "running") - for p in psutil.process_iter(): - if str(p.status) == '?': - self.fail("invalid status for pid %d" % p.pid) - - def test_username(self): - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - if POSIX: - import pwd - self.assertEqual(p.username, pwd.getpwuid(os.getuid()).pw_name) - elif WINDOWS: - expected_username = os.environ['USERNAME'] - expected_domain = os.environ['USERDOMAIN'] - domain, username = p.username.split('\\') - self.assertEqual(domain, expected_domain) - self.assertEqual(username, expected_username) - else: - p.username - - @skipUnless(WINDOWS or LINUX) - def test_getcwd(self): - sproc = get_test_subprocess() - wait_for_pid(sproc.pid) - p = psutil.Process(sproc.pid) - self.assertEqual(p.getcwd(), os.getcwd()) - - @skipUnless(WINDOWS or LINUX) - def test_getcwd_2(self): - cmd = [PYTHON, "-c", "import os, time; os.chdir('..'); time.sleep(10)"] - sproc = get_test_subprocess(cmd) - wait_for_pid(sproc.pid) - p = psutil.Process(sproc.pid) - time.sleep(0.1) - expected_dir = os.path.dirname(os.getcwd()) - self.assertEqual(p.getcwd(), expected_dir) - - def test_get_open_files(self): - # current process - p = psutil.Process(os.getpid()) - files = p.get_open_files() - self.assertFalse(TESTFN in files) - f = open(TESTFN, 'r') - time.sleep(.1) - filenames = [x.path for x in p.get_open_files()] - self.assertTrue(TESTFN in filenames) - f.close() - for file in filenames: - self.assertTrue(os.path.isfile(file)) - - # another process - cmdline = "import time; f = open(r'%s', 'r'); time.sleep(100);" % TESTFN - sproc = get_test_subprocess([PYTHON, "-c", cmdline]) - wait_for_pid(sproc.pid) - time.sleep(0.1) - p = psutil.Process(sproc.pid) - for x in range(100): - filenames = [x.path for x in p.get_open_files()] - if TESTFN in filenames: - break - time.sleep(.01) - else: - self.assertTrue(TESTFN in filenames) - for file in filenames: - self.assertTrue(os.path.isfile(file)) - # all processes - for proc in psutil.process_iter(): - try: - files = proc.get_open_files() - except psutil.Error: - pass - else: - for file in filenames: - self.assertTrue(os.path.isfile(file)) - - def test_get_open_files2(self): - # test fd and path fields - fileobj = open(TESTFN, 'r') - p = psutil.Process(os.getpid()) - for path, fd in p.get_open_files(): - if path == fileobj.name or fd == fileobj.fileno(): - break - else: - self.fail("no file found; files=%s" % repr(p.get_open_files())) - self.assertEqual(path, fileobj.name) - if WINDOWS: - self.assertEqual(fd, -1) - else: - self.assertEqual(fd, fileobj.fileno()) - # test positions - ntuple = p.get_open_files()[0] - self.assertEqual(ntuple[0], ntuple.path) - self.assertEqual(ntuple[1], ntuple.fd) - # test file is gone - fileobj.close() - self.assertTrue(fileobj.name not in p.get_open_files()) - - @skipUnless(SUPPORT_CONNECTIONS, warn=1) - def test_get_connections(self): - arg = "import socket, time;" \ - "s = socket.socket();" \ - "s.bind(('127.0.0.1', 0));" \ - "s.listen(1);" \ - "conn, addr = s.accept();" \ - "time.sleep(100);" - sproc = get_test_subprocess([PYTHON, "-c", arg]) - p = psutil.Process(sproc.pid) - for x in range(100): - cons = p.get_connections() - if cons: - break - time.sleep(.01) - self.assertEqual(len(cons), 1) - con = cons[0] - self.assertEqual(con.family, socket.AF_INET) - self.assertEqual(con.type, socket.SOCK_STREAM) - self.assertEqual(con.status, "LISTEN") - ip, port = con.local_address - self.assertEqual(ip, '127.0.0.1') - self.assertEqual(con.remote_address, ()) - if WINDOWS: - self.assertEqual(con.fd, -1) - else: - self.assertTrue(con.fd > 0) - # 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) - - @skipUnless(supports_ipv6()) - def test_get_connections_ipv6(self): - s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) - s.bind(('::1', 0)) - s.listen(1) - cons = psutil.Process(os.getpid()).get_connections() - s.close() - self.assertEqual(len(cons), 1) - self.assertEqual(cons[0].local_address[0], '::1') - - @skipUnless(hasattr(socket, "fromfd") and not WINDOWS) - def test_connection_fromfd(self): - sock = socket.socket() - sock.bind(('localhost', 0)) - sock.listen(1) - p = psutil.Process(os.getpid()) - for conn in p.get_connections(): - if conn.fd == sock.fileno(): - break - else: - sock.close() - self.fail("couldn't find socket fd") - dupsock = socket.fromfd(conn.fd, conn.family, conn.type) - try: - self.assertEqual(dupsock.getsockname(), conn.local_address) - self.assertNotEqual(sock.fileno(), dupsock.fileno()) - finally: - sock.close() - dupsock.close() - - @skipUnless(SUPPORT_CONNECTIONS, warn=1) - def test_get_connections_all(self): - - def check_address(addr, family): - if not addr: - return - ip, port = addr - self.assertTrue(isinstance(port, int)) - if family == socket.AF_INET: - ip = list(map(int, ip.split('.'))) - self.assertTrue(len(ip) == 4) - for num in ip: - self.assertTrue(0 <= num <= 255) - self.assertTrue(0 <= port <= 65535) - - # all values are supposed to match Linux's tcp_states.h states - # table across all platforms. - valid_states = ["ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1", - "FIN_WAIT2", "TIME_WAIT", "CLOSE", "CLOSE_WAIT", - "LAST_ACK", "LISTEN", "CLOSING", ""] - - 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);" - - 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") - - # launch various subprocess instantiating a socket of various - # families and tupes to enrich psutil results - tcp4_proc = get_test_subprocess([PYTHON, "-c", tcp4_template]) - udp4_proc = get_test_subprocess([PYTHON, "-c", udp4_template]) - if supports_ipv6(): - tcp6_proc = get_test_subprocess([PYTHON, "-c", tcp6_template]) - udp6_proc = get_test_subprocess([PYTHON, "-c", udp6_template]) - else: - tcp6_proc = None - udp6_proc = None - - # --- check connections of all processes - - time.sleep(0.1) - for p in psutil.process_iter(): - try: - cons = p.get_connections() - except (psutil.NoSuchProcess, psutil.AccessDenied): - pass - else: - for conn in cons: - self.assertTrue(conn.type in (socket.SOCK_STREAM, - socket.SOCK_DGRAM)) - self.assertTrue(conn.family in (socket.AF_INET, - socket.AF_INET6)) - check_address(conn.local_address, conn.family) - check_address(conn.remote_address, conn.family) - if conn.status not in valid_states: - self.fail("%s is not a valid status" %conn.status) - # actually try to bind the local socket; ignore IPv6 - # sockets as their address might be represented as - # an IPv4-mapped-address (e.g. "::127.0.0.1") - # and that's rejected by bind() - if conn.family == socket.AF_INET: - s = socket.socket(conn.family, conn.type) - s.bind((conn.local_address[0], 0)) - s.close() - - if not WINDOWS and hasattr(socket, 'fromfd'): - dupsock = None - try: - try: - dupsock = socket.fromfd(conn.fd, conn.family, - conn.type) - except (socket.error, OSError): - err = sys.exc_info()[1] - if err.args[0] == errno.EBADF: - continue - else: - raise - # python >= 2.5 - if hasattr(dupsock, "family"): - self.assertEqual(dupsock.family, conn.family) - self.assertEqual(dupsock.type, conn.type) - finally: - if dupsock is not None: - dupsock.close() - - - # --- check matches against subprocesses - - for p in psutil.Process(os.getpid()).get_children(): - for conn in p.get_connections(): - # TCP v4 - if p.pid == tcp4_proc.pid: - self.assertEqual(conn.family, socket.AF_INET) - self.assertEqual(conn.type, socket.SOCK_STREAM) - self.assertEqual(conn.local_address[0], "127.0.0.1") - self.assertEqual(conn.remote_address, ()) - self.assertEqual(conn.status, "LISTEN") - # UDP v4 - elif p.pid == udp4_proc.pid: - self.assertEqual(conn.family, socket.AF_INET) - self.assertEqual(conn.type, socket.SOCK_DGRAM) - self.assertEqual(conn.local_address[0], "127.0.0.1") - self.assertEqual(conn.remote_address, ()) - self.assertEqual(conn.status, "") - # TCP v6 - elif p.pid == getattr(tcp6_proc, "pid", None): - self.assertEqual(conn.family, socket.AF_INET6) - self.assertEqual(conn.type, socket.SOCK_STREAM) - self.assertTrue(conn.local_address[0] in ("::", "::1")) - self.assertEqual(conn.remote_address, ()) - self.assertEqual(conn.status, "LISTEN") - # UDP v6 - elif p.pid == getattr(udp6_proc, "pid", None): - self.assertEqual(conn.family, socket.AF_INET6) - self.assertEqual(conn.type, socket.SOCK_DGRAM) - self.assertTrue(conn.local_address[0] in ("::", "::1")) - self.assertEqual(conn.remote_address, ()) - self.assertEqual(conn.status, "") - - def test_parent_ppid(self): - 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) - # no other process is supposed to have us as parent - for p in psutil.process_iter(): - if p.pid == sproc.pid: - continue - self.assertTrue(p.ppid != this_parent) - - def test_get_children(self): - p = psutil.Process(os.getpid()) - self.assertEqual(p.get_children(), []) - sproc = get_test_subprocess() - children = p.get_children() - self.assertEqual(len(children), 1) - self.assertEqual(children[0].pid, sproc.pid) - self.assertEqual(children[0].ppid, os.getpid()) - - def test_suspend_resume(self): - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.suspend() - time.sleep(0.1) - self.assertEqual(p.status, psutil.STATUS_STOPPED) - self.assertEqual(str(p.status), "stopped") - p.resume() - self.assertTrue(p.status != psutil.STATUS_STOPPED) - - def test_invalid_pid(self): - self.assertRaises(ValueError, psutil.Process, "1") - self.assertRaises(ValueError, psutil.Process, None) - # Refers to Issue #12 - self.assertRaises(psutil.NoSuchProcess, psutil.Process, -1) - - def test_zombie_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 - # Refers to Issue #15 - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.kill() - p.wait() - - for name in dir(p): - if name.startswith('_')\ - or name in ('pid', 'send_signal', 'is_running', 'set_ionice', - 'wait'): - continue - try: - meth = getattr(p, name) - if callable(meth): - meth() - except psutil.NoSuchProcess: - pass - else: - self.fail("NoSuchProcess exception not raised for %r" % name) - - # other methods - try: - if os.name == 'posix': - p.nice = 1 - else: - p.nice = psutil.NORMAL_PRIORITY_CLASS - except psutil.NoSuchProcess: - pass - else: - self.fail("exception not raised") - if hasattr(p, 'set_ionice'): - self.assertRaises(psutil.NoSuchProcess, p.set_ionice, 2) - self.assertRaises(psutil.NoSuchProcess, p.send_signal, signal.SIGTERM) - self.assertFalse(p.is_running()) - - def test__str__(self): - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - self.assertTrue(str(sproc.pid) in str(p)) - # python shows up as 'Python' in cmdline on OS X so test fails on OS X - if not OSX: - self.assertTrue(os.path.basename(PYTHON) in str(p)) - sproc = get_test_subprocess() - p = psutil.Process(sproc.pid) - p.kill() - p.wait() - self.assertTrue(str(sproc.pid) in str(p)) - self.assertTrue("terminated" in str(p)) - - def test_fetch_all(self): - valid_procs = 0 - excluded_names = ['send_signal', 'suspend', 'resume', 'terminate', - 'kill', 'wait'] - excluded_names += ['get_cpu_percent', 'get_children'] - # XXX - skip slow lsof implementation; - if BSD: - excluded_names += ['get_open_files', 'get_connections'] - if OSX: - excluded_names += ['get_connections'] - 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) - - for p in psutil.process_iter(): - for name in attrs: - try: - try: - attr = getattr(p, name, None) - if attr is not None and callable(attr): - ret = attr() - else: - ret = attr - valid_procs += 1 - except (psutil.NoSuchProcess, psutil.AccessDenied): - err = sys.exc_info()[1] - self.assertEqual(err.pid, p.pid) - if err.name: - self.assertEqual(err.name, p.name) - self.assertTrue(str(err)) - self.assertTrue(err.msg) - else: - if name == 'parent' or ret in (0, 0.0, [], None): - continue - self.assertTrue(ret) - if name == "exe": - self.assertTrue(os.path.isfile(ret)) - elif name == "getcwd": - # XXX - temporary fix; on my Linux box - # chrome process cws is errnously reported - # as /proc/4144/fdinfo whichd doesn't exist - if 'chrome' in p.name: - continue - self.assertTrue(os.path.isdir(ret)) - except Exception: - err = sys.exc_info()[1] - trace = traceback.format_exc() - self.fail('%s\nmethod=%s, pid=%s, retvalue=%s' - %(trace, name, p.pid, repr(ret))) - - # we should always have a non-empty list, not including PID 0 etc. - # special cases. - self.assertTrue(valid_procs > 0) - - @skipIf(LINUX) - def test_pid_0(self): - # Process(0) is supposed to work on all platforms except Linux - p = psutil.Process(0) - self.assertTrue(p.name) - - if os.name == 'posix': - self.assertEqual(p.uids.real, 0) - self.assertEqual(p.gids.real, 0) - - self.assertTrue(p.ppid in (0, 1)) - #self.assertEqual(p.exe, "") - self.assertEqual(p.cmdline, []) - try: - p.get_num_threads() - except psutil.AccessDenied: - pass - - if OSX : #and os.geteuid() != 0: - self.assertRaises(psutil.AccessDenied, p.get_memory_info) - self.assertRaises(psutil.AccessDenied, p.get_cpu_times) - else: - p.get_memory_info() - - # username property - if POSIX: - self.assertEqual(p.username, 'root') - elif WINDOWS: - self.assertEqual(p.username, 'NT AUTHORITY\\SYSTEM') - else: - p.username - - self.assertTrue(0 in psutil.get_pid_list()) - self.assertTrue(psutil.pid_exists(0)) - - def test_Popen(self): - # Popen class test - cmd = [PYTHON, "-c", "import time; time.sleep(3600);"] - proc = psutil.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - try: - proc.name - proc.stdin - self.assertTrue(hasattr(proc, 'name')) - self.assertTrue(hasattr(proc, 'stdin')) - self.assertRaises(AttributeError, getattr, proc, 'foo') - finally: - proc.kill() - proc.wait() - - -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 - PROCESS_UID = os.getuid() - PROCESS_GID = os.getgid() - - def __init__(self, *args, **kwargs): - TestCase.__init__(self, *args, **kwargs) - # re-define all existent test methods in order to - # ignore AccessDenied exceptions - for attr in [x for x in dir(self) if x.startswith('test')]: - meth = getattr(self, attr) - def test_(self): - try: - meth() - except psutil.AccessDenied: - pass - setattr(self, attr, types.MethodType(test_, self)) - - def setUp(self): - os.setegid(1000) - os.seteuid(1000) - TestCase.setUp(self) - - def tearDown(self): - os.setegid(self.PROCESS_UID) - os.seteuid(self.PROCESS_GID) - TestCase.tearDown(self) - - def test_nice(self): - try: - psutil.Process(os.getpid()).nice = -1 - except psutil.AccessDenied: - pass - else: - self.fail("exception not raised") - - -def test_main(): - tests = [] - test_suite = unittest.TestSuite() - tests.append(TestCase) - - if POSIX: - from _posix import PosixSpecificTestCase - tests.append(PosixSpecificTestCase) - - # import the specific platform test suite - if LINUX: - from _linux import LinuxSpecificTestCase as stc - elif WINDOWS: - from _windows import WindowsSpecificTestCase as stc - elif OSX: - 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(warnings.warn, "Couldn't run limited user tests (" - "super-user privileges are required)", RuntimeWarning) - - for test_class in tests: - test_suite.addTest(unittest.makeSuite(test_class)) - - f = open(TESTFN, 'w') - f.close() - atexit.register(lambda: os.remove(TESTFN)) - - unittest.TextTestRunner(verbosity=2).run(test_suite) - DEVNULL.close() - -if __name__ == '__main__': - test_main() |