Backed out changeset 99809c2e06ae since it wasn't supposed to get pushed. r=me

This commit is contained in:
Jared Wein 2018-03-03 00:17:58 -05:00
Родитель 8368d36a52
Коммит b6b0f69f65
153 изменённых файлов: 36057 добавлений и 14533 удалений

Просмотреть файл

@ -337,7 +337,7 @@ class DesktopUnittest(TestingMixin, MercurialScript, BlobUploadMixin, MozbaseMix
dirs = self.query_abs_dirs() dirs = self.query_abs_dirs()
self.register_virtualenv_module(name='pip>=1.5') self.register_virtualenv_module(name='pip>=1.5')
self.register_virtualenv_module('psutil==3.1.1', method='pip') self.register_virtualenv_module('psutil==5.4.3', method='pip')
self.register_virtualenv_module(name='mock') self.register_virtualenv_module(name='mock')
self.register_virtualenv_module(name='simplejson') self.register_virtualenv_module(name='simplejson')

Просмотреть файл

@ -3,7 +3,7 @@ twisted==10.2.0
# websocket adapter for twisted, might be built into twisted someday # websocket adapter for twisted, might be built into twisted someday
txws==0.9.1 txws==0.9.1
psutil==3.1.1 psutil==5.4.3
# needed by txws, but pypi doesn't know about it # needed by txws, but pypi doesn't know about it
six==1.10.0 six==1.10.0

217
third_party/python/psutil/CREDITS поставляемый
Просмотреть файл

@ -20,6 +20,32 @@ C: Italy
E: g.rodola@gmail.com E: g.rodola@gmail.com
W: http://grodola.blogspot.com/ W: http://grodola.blogspot.com/
Experts
=======
Github usernames of people to CC on github when in need of help.
- NetBSD:
- 0-wiz-0, Thomas Klausner
- ryoqun, Ryo Onodera
- OpenBSD:
- landryb, Landry Breuil
- FreeBSD:
- glebius, Gleb Smirnoff (#1013)
- sunpoet, Po-Chuan Hsieh (pkg maintainer, #1105)
- kostikbel, Konstantin Belousov (#1105)
- OSX:
- whitlockjc, Jeremy Whitlock
- Windows:
- mrjefftang, Jeff Tang
- wj32, Wen Jia Liu
- fbenkstein, Frank Benkstein
- SunOS:
- wiggin15, Arnon Yaari
- alxchk, Oleksii Shevchuk
- AIX:
- wiggin15, Arnon Yaari (maintainer)
Contributors Contributors
============ ============
@ -29,11 +55,24 @@ E: jloden@gmail.com
D: original co-author, initial design/bootstrap and occasional bug fixes D: original co-author, initial design/bootstrap and occasional bug fixes
W: http://www.jayloden.com W: http://www.jayloden.com
N: Arnon Yaari (wiggin15)
W: https://github.com/wiggin15
I: 517, 607, 610, 1131, 1123, 1130, 1154, 1164, 1174, 1177
N: Jeff Tang
W: https://github.com/mrjefftang
I: 340, 529, 616, 653, 654, 648, 641
N: Jeremy Whitlock N: Jeremy Whitlock
E: jcscoobyrs@gmail.com E: jcscoobyrs@gmail.com
D: great help with OSX C development. D: great help with OSX C development.
I: 125, 150, 174, 206 I: 125, 150, 174, 206
N: Landry Breuil
W: https://github.com/landryb
D: OpenBSD implementation.
I: 615
N: wj32 N: wj32
E: wj32.64@gmail.com E: wj32.64@gmail.com
D: process username() and get_connections() on Windows D: process username() and get_connections() on Windows
@ -56,6 +95,14 @@ W: http://daviddaeschler.com
D: some contributions to initial design/bootstrap plus occasional bug fixing D: some contributions to initial design/bootstrap plus occasional bug fixing
I: 522, 536 I: 522, 536
N: Thomas Klausner
W: https://github.com/0-wiz-0
I: #557
N: Ryo Onodera
W: https://github.com/ryoon
I: #557
N: cjgohlke N: cjgohlke
E: cjgohlke@gmail.com E: cjgohlke@gmail.com
D: Windows 64 bit support D: Windows 64 bit support
@ -253,10 +300,6 @@ N: msabramo
E: msabramo@gmail.com E: msabramo@gmail.com
I: 492 I: 492
N: Jeff Tang
W: https://github.com/mrjefftang
I: 340, 529, 616, 653, 654
N: Yaolong Huang N: Yaolong Huang
E: airekans@gmail.com E: airekans@gmail.com
W: http://airekans.github.io/ W: http://airekans.github.io/
@ -267,8 +310,9 @@ W: https://github.com/anders-chrigstrom
I: 496 I: 496
N: spacewander N: spacewander
W: https://github.com/spacewander
E: spacewanderlzx@gmail.com E: spacewanderlzx@gmail.com
I: 561 I: 561, 603
N: Sylvain Mouquet N: Sylvain Mouquet
E: sylvain.mouquet@gmail.com E: sylvain.mouquet@gmail.com
@ -308,3 +352,166 @@ N: Árni Már Jónsson
E: Reykjavik, Iceland E: Reykjavik, Iceland
E: https://github.com/arnimarj E: https://github.com/arnimarj
I: 634 I: 634
N: Bart van Kleef
W: https://github.com/bkleef
I: 664
N: Steven Winfield
W: https://github.com/stevenwinfield
I: 672
N: sk6249
W: https://github.com/sk6249
I: 670
N: maozguttman
W: https://github.com/maozguttman
I: 659
N: dasumin
W: https://github.com/dasumin
I: 541
N: Mike Sarahan
W: https://github.com/msarahan
I: 688
N: Syohei YOSHIDA
W: https://github.com/syohex
I: 730
N: Frank Benkstein
W: https://github.com/fbenkstein
I: 732, 733
N: Visa Hankala
E: visa@openbsd.org
I: 741
N: Sebastian-Gabriel Brestin
C: Romania
E: sebastianbrestin@gmail.com
I: 704
N: Timmy Konick
W: https://github.com/tijko
I: 751
N: mpderbec
W: https://github.com/mpderbec
I: 660
N: Mozilla Foundation
D: sample code for process USS memory.
N: wxwright
W: https://github.com/wxwright
I: 776
N: Farhan Khan
E: khanzf@gmail.com
I: 823
N: Jake Omann
E: https://github.com/jomann09
I: 816, 775
N: Jeremy Humble
W: https://github.com/jhumble
I: 863
N: Ilya Georgievsky
W: https://github.com/xBeAsTx
I: 870
N: Yago Jesus
W: https://github.com/YJesus
I: 798
N: Andre Caron
C: Montreal, QC, Canada
E: andre.l.caron@gmail.com
W: https://github.com/AndreLouisCaron
I: 880
N: ewedlund
W: https://github.com/ewedlund
I: 874
N: Arcadiy Ivanov
W: https://github.com/arcivanov
I: 919
N: Max Bélanger
W: https://github.com/maxbelanger
I: 936, 1133
N: Pierre Fersing
C: France
E: pierre.fersing@bleemeo.com
I: 950
N: Thiago Borges Abdnur
W: https://github.com/bolaum
I: 959
N: Nicolas Hennion
W: https://github.com/nicolargo
I: 974
N: Baruch Siach
W: https://github.com/baruchsiach
I: 872
N: Danek Duvall
W: https://github.com/dhduvall
I: 1002
N: Alexander Hasselhuhn
C: Germany
W: https://github.com/alexanha
N: Himanshu Shekhar
W: https://github.com/himanshub16
I: 1036
N: Yannick Gingras
W: https://github.com/ygingras
I: 1057
N: Gleb Smirnoff
W: https://github.com/glebius
I: 1042, 1079
N: Oleksii Shevchuk
W: https://github.com/alxchk
I: 1077, 1093, 1091
N: Prodesire
W: https://github.com/Prodesire
I: 1138
N: Sebastian Saip
W: https://github.com/ssaip
I: 1141
N: Jakub Bacic
W: https://github.com/jakub-bacic
I: 1127
N: Akos Kiss
W: https://github.com/akosthekiss
I: 1150
N: Adrian Page
W: https://github.com/adpag
I: 1159, 1160, 1161
N: Matthew Long
W: https://github.com/matray
I: 1167
N: janderbrain
W: https://github.com/janderbrain
I: 1169

209
third_party/python/psutil/DEVGUIDE.rst поставляемый Normal file
Просмотреть файл

@ -0,0 +1,209 @@
=======================
Setup and running tests
=======================
If you plan on hacking on psutil this is what you're supposed to do first:
- clone the GIT repository:
.. code-block:: bash
$ git clone git@github.com:giampaolo/psutil.git
- install test deps and GIT hooks:
.. code-block:: bash
make setup-dev-env
- run tests:
.. code-block:: bash
make test
- bear in mind that ``make``
(see `Makefile <https://github.com/giampaolo/psutil/blob/master/Makefile>`_)
is the designated tool to run tests, build, install etc. and that it is also
available on Windows
(see `make.bat <https://github.com/giampaolo/psutil/blob/master/make.bat>`_).
- do not use ``sudo``; ``make install`` installs psutil as a limited user in
"edit" mode; also ``make setup-dev-env`` installs deps as a limited user.
- use `make help` to see the list of available commands.
============
Coding style
============
- python code strictly follows `PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_
styling guides and this is enforced by ``make install-git-hooks``.
- C code strictly follows `PEP 7 <https://www.python.org/dev/peps/pep-0007/>`_
styling guides.
========
Makefile
========
Some useful make commands:
.. code-block:: bash
make install # install
make setup-dev-env # install useful dev libs (pyflakes, unittest2, etc.)
make test # run unit tests
make test-memleaks # run memory leak tests
make test-coverage # run test coverage
make flake8 # run PEP8 linter
There are some differences between ``make`` on UNIX and Windows.
For instance, to run a specific Python version. On UNIX:
.. code-block:: bash
make test PYTHON=python3.5
On Windows:
.. code-block:: bat
set PYTHON=C:\python35\python.exe && make test
...or:
.. code-block:: bat
make -p 35 test
If you want to modify psutil and run a script on the fly which uses it do
(on UNIX):
.. code-block:: bash
make test TSCRIPT=foo.py
On Windows:
.. code-block:: bat
set TSCRIPT=foo.py && make test
====================
Adding a new feature
====================
Usually the files involved when adding a new functionality are:
.. code-block:: bash
psutil/__init__.py # main psutil namespace
psutil/_ps{platform}.py # python platform wrapper
psutil/_psutil_{platform}.c # C platform extension
psutil/_psutil_{platform}.h # C header file
psutil/tests/test_process|system.py # main test suite
psutil/tests/test_{platform}.py # platform specific test suite
Typical process occurring when adding a new functionality (API):
- define the new function in ``psutil/__init__.py``.
- write the platform specific implementation in ``psutil/_ps{platform}.py``
(e.g. ``psutil/_pslinux.py``).
- if the change requires C, write the C implementation in
``psutil/_psutil_{platform}.c`` (e.g. ``psutil/_psutil_linux.c``).
- write a generic test in ``psutil/tests/test_system.py`` or
``psutil/tests/test_process.py``.
- if possible, write a platform specific test in
``psutil/tests/test_{platform}.py`` (e.g. ``test_linux.py``).
This usually means testing the return value of the new feature against
a system CLI tool.
- update doc in ``doc/index.py``.
- update ``HISTORY.rst``.
- update ``README.rst`` (if necessary).
- make a pull request.
===================
Make a pull request
===================
- fork psutil
- create your feature branch (``git checkout -b my-new-feature``)
- commit your changes (``git commit -am 'add some feature'``)
- push to the branch (``git push origin my-new-feature``)
- create a new pull request
======================
Continuous integration
======================
All of the services listed below are automatically run on ``git push``.
Unit tests
----------
Tests are automatically run for every GIT push on **Linux**, **OSX** and
**Windows** by using:
- `Travis <https://travis-ci.org/giampaolo/psutil>`_ (Linux, OSX)
- `Appveyor <https://ci.appveyor.com/project/giampaolo/psutil>`_ (Windows)
Test files controlling these are
`.travis.yml <https://github.com/giampaolo/psutil/blob/master/.travis.yml>`_
and
`appveyor.yml <https://github.com/giampaolo/psutil/blob/master/appveyor.yml>`_.
Both services run psutil test suite against all supported python version
(2.6 - 3.6).
Two icons in the home page (README) always show the build status:
.. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20OSX
:target: https://travis-ci.org/giampaolo/psutil
:alt: Linux tests (Travis)
.. image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
:target: https://ci.appveyor.com/project/giampaolo/psutil
:alt: Windows tests (Appveyor)
OSX, BSD, AIX and Solaris are currently tested manually (sigh!).
Test coverage
-------------
Test coverage is provided by `coveralls.io <https://coveralls.io/github/giampaolo/psutil>`_,
it is controlled via `.travis.yml <https://github.com/giampaolo/psutil/blob/master/.travis.yml>`_
and it is updated on every git push.
An icon in the home page (README) always shows the last coverage percentage:
.. image:: https://coveralls.io/repos/giampaolo/psutil/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
=============
Documentation
=============
- doc source code is written in a single file: `/docs/index.rst <https://raw.githubusercontent.com/giampaolo/psutil/master/docs/index.rst>`_.
- it uses `RsT syntax <http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
and it's built with `sphinx <http://sphinx-doc.org/>`_.
- doc can be built with ``make setup-dev-env; cd docs; make html``.
- public doc is hosted on http://psutil.readthedocs.io/
=======================
Releasing a new version
=======================
These are notes for myself (Giampaolo):
- ``make release``
- post announce (``make print-announce``) on psutil and python-announce mailing
lists, twitter, g+, blog.
=============
FreeBSD notes
=============
- setup:
.. code-block:: bash
pkg install python python3 gcc git vim screen bash
chsh -s /usr/local/bin/bash user # set bash as default shell
- ``/usr/src`` contains the source codes for all installed CLI tools (grep in it).

3062
third_party/python/psutil/HISTORY.rst поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

165
third_party/python/psutil/IDEAS поставляемый Normal file
Просмотреть файл

@ -0,0 +1,165 @@
TODO
====
A collection of ideas and notes about stuff to implement in future versions.
"#NNN" occurrences refer to bug tracker issues at:
https://github.com/giampaolo/psutil/issues
PLATFORMS
=========
- #355: Android (with patch)
- #82: Cygwin (PR at #998)
- #276: GNU/Hurd
- #693: Windows Nano
- DragonFlyBSD
- HP-UX
FEATURES
========
- #371: sensors_temperatures() at least for OSX.
- #669: Windows / net_if_addrs(): return broadcast addr.
- #550: CPU info (frequency, architecture, threads per core, cores per socket,
sockets, ...)
- #772: extended net_io_counters() metrics.
- #900: wheels for OSX and Linux.
- #922: extended net_io_stats() info.
- #914: extended platform specific process info.
- #898: wifi stats
- #893: (BSD) process environ
- #809: (BSD) per-process resource limits (rlimit()).
- (UNIX) process root (different from cwd)
- #782: (UNIX) process num of signals received.
- (Linux) locked files via /proc/locks:
https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-locks.html
- #269: NIC rx/tx queue. This should probably go into net_if_stats().
Figure out on what platforms this is supported:
Linux: yes
Others: ?
- Process.threads(): thread names; patch for OSX available at:
https://code.google.com/p/plcrashreporter/issues/detail?id=65
Sample code:
https://github.com/janmojzis/pstree/blob/master/proc_kvm.c
- Asynchronous psutil.Popen (see http://bugs.python.org/issue1191964)
- (Windows) fall back on using WMIC for Process methods returning AccessDenied
- #613: thread names.
- #604: emulate os.getloadavg() on Windows
- scripts/taskmgr-gui.py (using tk).
- system-wide number of open file descriptors:
- https://jira.hyperic.com/browse/SIGAR-30
- Number of system threads.
- Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684824(v=vs.85).aspx
- Doc / wiki which compares similarities between UNIX cli tools and psutil.
Example:
```
df -a -> psutil.disk_partitions
lsof -> psutil.Process.open_files() and psutil.Process.open_connections()
killall-> (actual script)
tty -> psutil.Process.terminal()
who -> psutil.users()
```
- psutil.proc_tree() something which obtains a {pid:ppid, ...} dict for
all running processes in one shot. This can be factored out from
Process.children() and exposed as a first class function.
PROS: on Windows we can take advantage of _psutil_windows.ppid_map()
which is faster than iterating over all pids and calling ppid().
CONS: scripts/pstree.py shows this can be easily done in the user code
so maybe it's not worth the addition.
- advanced cmdline interface exposing the whole API and providing different
kind of outputs (e.g. pprinted, colorized, json).
- [Linux]: process cgroups (http://en.wikipedia.org/wiki/Cgroups). They look
similar to prlimit() in terms of functionality but uglier (they should allow
limiting per-process network IO resources though, which is great). Needs
further reading.
- Python 3.3. exposed different sched.h functions:
http://docs.python.org/dev/whatsnew/3.3.html#os
http://bugs.python.org/issue12655
http://docs.python.org/dev/library/os.html#interface-to-the-scheduler
It might be worth to take a look and figure out whether we can include some
of those in psutil.
Also, we can probably reimplement wait_pid() on POSIX which is currently
implemented as a busy-loop.
- os.times() provides 'elapsed' times (cpu_times() might).
- ...also guest_time and cguest_time on Linux.
- Enrich exception classes hierarchy on Python >= 3.3 / post PEP-3151 so that:
- NoSuchProcess inherits from ProcessLookupError
- AccessDenied inherits from PermissionError
- TimeoutExpired inherits from TimeoutError (debatable)
See: http://docs.python.org/3/library/exceptions.html#os-exceptions
- Process.threads() might grow an extra "id" parameter so that it can be
used as such:
```
>>> p = psutil.Process(os.getpid())
>>> p.threads(id=psutil.current_thread_id())
thread(id=2539, user_time=0.03, system_time=0.02)
>>>
```
Note: this leads to questions such as "should we have a custom NoSuchThread
exception? Also see issue #418.
Note #2: this would work with os.getpid() only.
psutil.current_thread_id() might be desirable as per issue #418 though.
- should psutil.TimeoutExpired exception have a 'msg' kwarg similar to
NoSuchProcess and AccessDenied? Not that we need it, but currently we
cannot raise a TimeoutExpired exception with a specific error string.
- process_iter() might grow an "attrs" parameter similar to Process.as_dict()
invoke the necessary methods and include the results into a "cache"
attribute attached to the returned Process instances so that one can avoid
catching NSP and AccessDenied:
for p in process_iter(attrs=['cpu_percent']):
print(p.cache['cpu_percent'])
This also leads questions as whether we should introduce a sorting order.
- round Process.memory_percent() result?
- #550: number of threads per core.
BUGFIXES
========
- #600: windows / open_files(): support network file handles.
REJECTED
========
- #550: threads per core
RESOURCES
=========
- sigar: https://github.com/hyperic/sigar (Java)
- zabbix: https://zabbix.org/wiki/Get_Zabbix
- libstatgrab: http://www.i-scream.org/libstatgrab/
- top: http://www.unixtop.org/

220
third_party/python/psutil/INSTALL.rst поставляемый
Просмотреть файл

@ -1,116 +1,160 @@
============================ Install pip
Installing using pip on UNIX ===========
============================
The easiest way to install psutil on UNIX is by using pip (but first you might pip is the easiest way to install psutil.
need to install python header files; see later). It is shipped by default with Python 2.7.9+ and 3.4+. For other Python versions
First install pip:: you can install it manually.
On Linux or via wget:
$ wget https://bootstrap.pypa.io/get-pip.py .. code-block:: bash
$ python get-pip.py
...then run:: wget https://bootstrap.pypa.io/get-pip.py -O - | python
$ pip install psutil On OSX or via curl:
You may need to install gcc and python header files first (see later). .. code-block:: bash
python < <(curl -s https://bootstrap.pypa.io/get-pip.py)
On Windows, `download pip <https://pip.pypa.io/en/latest/installing/>`__, open
cmd.exe and install it:
.. code-block:: bat
C:\Python27\python.exe get-pip.py
Permission issues (UNIX)
========================
The commands below assume you're running as root.
If you're not or you bump into permission errors you can either:
* prepend ``sudo``, e.g.:
.. code-block:: bash
sudo pip install psutil
* install psutil for your user only (not at system level):
.. code-block:: bash
pip install --user psutil
Linux
=====
Ubuntu / Debian:
.. code-block:: bash
sudo apt-get install gcc python-dev python-pip
pip install psutil
RedHat / CentOS:
===================== .. code-block:: bash
Installing on Windows
=====================
Just get the right installer for your Python version and architecture from: sudo yum install gcc python-devel python-pip
https://pypi.python.org/pypi/psutil/#downloads pip install psutil
Since wheels installers are also available you may also use pip.
If you're on Python 3 use ``python3-dev`` and ``python3-pip`` instead.
======================================== OSX
Compiling on Windows using Visual Studio ===
========================================
In order to compile psutil on Windows you'll need Visual Studio (Mingw32 is Install `Xcode <https://developer.apple.com/downloads/?name=Xcode>`__
no longer supported). You must have the same version of Visual Studio used to compile first, then:
your installation of Python, that is::
* Python 2.6: VS 2008 .. code-block:: bash
* Python 2.7: VS 2008
* Python 3.3, 3.4: VS 2010 (you can download it from `MS website <http://www.visualstudio.com/downloads/download-visual-studio-vs#d-2010-express>`_)
* Python 3.5: `VS 2015 UP <http://www.visualstudio.com/en-au/news/vs2015-preview-vs>`_
...then run:: pip install psutil
setup.py build Windows
=======
...or:: The easiest way to install psutil on Windows is to just use the pre-compiled
exe/wheel installers hosted on
`PYPI <https://pypi.python.org/pypi/psutil/#downloads>`__ via pip:
make.bat build .. code-block:: bat
C:\Python27\python.exe -m pip install psutil
If you want to compile psutil from sources you'll need **Visual Studio**
(Mingw32 is no longer supported):
* Python 2.6, 2.7: `VS-2008 <http://www.microsoft.com/en-us/download/details.aspx?id=44266>`__
* Python 3.3, 3.4: `VS-2010 <http://www.visualstudio.com/downloads/download-visual-studio-vs#d-2010-express>`__
* Python 3.5+: `VS-2015 <http://www.visualstudio.com/en-au/news/vs2015-preview-vs>`__
Compiling 64 bit versions of Python 2.6 and 2.7 with VS 2008 requires Compiling 64 bit versions of Python 2.6 and 2.7 with VS 2008 requires
Windows SDK and .NET Framework 3.5 SP1 to be installed first. `Windows SDK and .NET Framework 3.5 SP1 <https://www.microsoft.com/en-us/download/details.aspx?id=3138>`__.
Once you have those run vcvars64.bat, then compile: Once installed run vcvars64.bat, then you can finally compile (see
http://stackoverflow.com/questions/11072521/ `here <http://stackoverflow.com/questions/11072521/>`__).
To compile / install psutil from sources on Windows run:
=================== .. code-block:: bat
Installing on Linux
===================
gcc is required and so the python headers. They can easily be installed by make.bat build
using the distro package manager. For example, on Debian and Ubuntu:: make.bat install
$ sudo apt-get install gcc python-dev FreeBSD
=======
...on Redhat and CentOS:: .. code-block:: bash
$ sudo yum install gcc python-devel pkg install python gcc
python -m pip install psutil
Once done, you can build/install psutil with:: OpenBSD
=======
$ python setup.py install .. code-block:: bash
export PKG_PATH="http://ftp.openbsd.org/pub/OpenBSD/`uname -r`/packages/`arch -s`/"
pkg_add -v python gcc
python -m pip install psutil
NetBSD
======
.. code-block:: bash
export PKG_PATH="ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All"
pkg_add -v pkgin
pkgin install python gcc
python -m pip install psutil
Solaris
=======
If ``cc`` compiler is not installed create a symlink to ``gcc``:
.. code-block:: bash
sudo ln -s /usr/bin/gcc /usr/local/bin/cc
Install:
.. code-block:: bash
pkg install gcc
python -m pip install psutil
Install from sources
====================
.. code-block:: bash
git clone https://github.com/giampaolo/psutil.git
cd psutil
python setup.py install
================== Dev Guide
Installing on OS X =========
==================
OS X installation from source will require gcc which you can obtain as part of If you plan on hacking on psutil you may want to take a look at the
the 'XcodeTools' installer from Apple. Then you can run the standard distutils `dev guide <https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst>`__.
commands.
To build only::
$ python setup.py build
To install and build::
$ python setup.py install
=====================
Installing on FreeBSD
=====================
The same compiler used to install Python must be present on the system in order
to build modules using distutils. Assuming it is installed, you can build using
the standard distutils commands.
Build only::
$ python setup.py build
Install and build::
$ python setup.py install
========
Makefile
========
A makefile is available for both UNIX and Windows (make.bat). It provides
some automations for the tasks described above and might be preferred over
using setup.py. With it you can::
$ make install # just install (in --user mode)
$ make uninstall # uninstall (needs pip)
$ make test # run tests
$ make clean # remove installation files

131
third_party/python/psutil/MANIFEST.in поставляемый
Просмотреть файл

@ -1,22 +1,131 @@
include .coveragerc include .coveragerc
include .git-pre-commit include .git-pre-commit
include .git-pre-commit
include .gitignore include .gitignore
include .travis.yml
include CREDITS include CREDITS
include DEVGUIDE.rst
include HISTORY.rst include HISTORY.rst
include IDEAS
include INSTALL.rst include INSTALL.rst
include LICENSE include LICENSE
include make.bat
include Makefile
include MANIFEST.in include MANIFEST.in
include Makefile
include README.rst include README.rst
include docs/Makefile
include docs/README
include docs/_static/copybutton.js
include docs/_static/css/custom.css
include docs/_static/favicon.ico
include docs/_static/sidebar.js
include docs/conf.py
include docs/index.rst
include docs/make.bat
include make.bat
include psutil/DEVNOTES
include psutil/__init__.py
include psutil/_common.py
include psutil/_compat.py
include psutil/_exceptions.py
include psutil/_psaix.py
include psutil/_psbsd.py
include psutil/_pslinux.py
include psutil/_psosx.py
include psutil/_psposix.py
include psutil/_pssunos.py
include psutil/_psutil_aix.c
include psutil/_psutil_bsd.c
include psutil/_psutil_common.c
include psutil/_psutil_common.h
include psutil/_psutil_linux.c
include psutil/_psutil_osx.c
include psutil/_psutil_posix.c
include psutil/_psutil_posix.h
include psutil/_psutil_sunos.c
include psutil/_psutil_windows.c
include psutil/_pswindows.py
include psutil/arch/aix/common.c
include psutil/arch/aix/common.h
include psutil/arch/aix/ifaddrs.c
include psutil/arch/aix/ifaddrs.h
include psutil/arch/aix/net_connections.c
include psutil/arch/aix/net_connections.h
include psutil/arch/aix/net_kernel_structs.h
include psutil/arch/freebsd/proc_socks.c
include psutil/arch/freebsd/proc_socks.h
include psutil/arch/freebsd/specific.c
include psutil/arch/freebsd/specific.h
include psutil/arch/freebsd/sys_socks.c
include psutil/arch/freebsd/sys_socks.h
include psutil/arch/netbsd/socks.c
include psutil/arch/netbsd/socks.h
include psutil/arch/netbsd/specific.c
include psutil/arch/netbsd/specific.h
include psutil/arch/openbsd/specific.c
include psutil/arch/openbsd/specific.h
include psutil/arch/osx/process_info.c
include psutil/arch/osx/process_info.h
include psutil/arch/solaris/environ.c
include psutil/arch/solaris/environ.h
include psutil/arch/solaris/v10/ifaddrs.c
include psutil/arch/solaris/v10/ifaddrs.h
include psutil/arch/windows/glpi.h
include psutil/arch/windows/inet_ntop.c
include psutil/arch/windows/inet_ntop.h
include psutil/arch/windows/ntextapi.h
include psutil/arch/windows/process_handles.c
include psutil/arch/windows/process_handles.h
include psutil/arch/windows/process_info.c
include psutil/arch/windows/process_info.h
include psutil/arch/windows/security.c
include psutil/arch/windows/security.h
include psutil/arch/windows/services.c
include psutil/arch/windows/services.h
include psutil/tests/README.rst
include psutil/tests/__init__.py
include psutil/tests/__main__.py
include psutil/tests/test_aix.py
include psutil/tests/test_bsd.py
include psutil/tests/test_connections.py
include psutil/tests/test_contracts.py
include psutil/tests/test_linux.py
include psutil/tests/test_memory_leaks.py
include psutil/tests/test_misc.py
include psutil/tests/test_osx.py
include psutil/tests/test_posix.py
include psutil/tests/test_process.py
include psutil/tests/test_sunos.py
include psutil/tests/test_system.py
include psutil/tests/test_unicode.py
include psutil/tests/test_windows.py
include scripts/battery.py
include scripts/cpu_distribution.py
include scripts/disk_usage.py
include scripts/fans.py
include scripts/free.py
include scripts/ifconfig.py
include scripts/internal/README
include scripts/internal/bench_oneshot.py
include scripts/internal/bench_oneshot_2.py
include scripts/internal/check_broken_links.py
include scripts/internal/download_exes.py
include scripts/internal/generate_manifest.py
include scripts/internal/print_announce.py
include scripts/internal/print_timeline.py
include scripts/internal/winmake.py
include scripts/iotop.py
include scripts/killall.py
include scripts/meminfo.py
include scripts/netstat.py
include scripts/nettop.py
include scripts/pidof.py
include scripts/pmap.py
include scripts/procinfo.py
include scripts/procsmem.py
include scripts/ps.py
include scripts/pstree.py
include scripts/sensors.py
include scripts/temperatures.py
include scripts/top.py
include scripts/who.py
include scripts/winservices.py
include setup.py include setup.py
include TODO
include tox.ini include tox.ini
recursive-exclude docs/_build *
recursive-include .appveyor/*
recursive-include docs *
recursive-include examples *.py
recursive-include psutil *.py *.c *.h
recursive-include test *.py README*

317
third_party/python/psutil/Makefile поставляемый
Просмотреть файл

@ -1,122 +1,269 @@
# Shortcuts for various tasks (UNIX only). # Shortcuts for various tasks (UNIX only).
# To use a specific Python version run: # To use a specific Python version run: "make install PYTHON=python3.3"
# $ make install PYTHON=python3.3 # You can set the variables below from the command line.
# You can set these variables from the command line. PYTHON = python
PYTHON = python TSCRIPT = psutil/tests/__main__.py
TSCRIPT = test/test_psutil.py ARGS =
# List of nice-to-have dev libs.
DEPS = \
argparse \
check-manifest \
coverage \
flake8 \
futures \
ipaddress \
mock==1.0.1 \
pep8 \
perf \
pyflakes \
requests \
setuptools \
sphinx \
twine \
unittest2 \
wheel
# In not in a virtualenv, add --user options for install commands.
INSTALL_OPTS = `$(PYTHON) -c "import sys; print('' if hasattr(sys, 'real_prefix') else '--user')"`
TEST_PREFIX = PYTHONWARNINGS=all PSUTIL_TESTING=1 PSUTIL_DEBUG=1
all: test all: test
clean: # ===================================================================
rm -f `find . -type f -name \*.py[co]` # Install
rm -f `find . -type f -name \*.so` # ===================================================================
rm -f `find . -type f -name .\*~`
rm -f `find . -type f -name \*.orig`
rm -f `find . -type f -name \*.bak`
rm -f `find . -type f -name \*.rej`
rm -rf `find . -type d -name __pycache__`
rm -rf *.core
rm -rf *.egg-info
rm -rf *\$testfile*
rm -rf .coverage
rm -rf .tox
rm -rf build
rm -rf dist
rm -rf docs/_build
rm -rf htmlcov
build: clean clean: ## Remove all build files.
$(PYTHON) setup.py build rm -rf `find . -type d -name __pycache__ \
@# copies *.so files in ./psutil directory in order to allow -o -type f -name \*.bak \
-o -type f -name \*.orig \
-o -type f -name \*.pyc \
-o -type f -name \*.pyd \
-o -type f -name \*.pyo \
-o -type f -name \*.rej \
-o -type f -name \*.so \
-o -type f -name \*.~ \
-o -type f -name \*\$testfn`
rm -rf \
*.core \
*.egg-info \
*\$testfn* \
.coverage \
.tox \
build/ \
dist/ \
docs/_build/ \
htmlcov/ \
tmp/
_:
build: _ ## Compile without installing.
# make sure setuptools is installed (needed for 'develop' / edit mode)
$(PYTHON) -c "import setuptools"
PYTHONWARNINGS=all $(PYTHON) setup.py build
@# copies compiled *.so files in ./psutil directory in order to allow
@# "import psutil" when using the interactive interpreter from within @# "import psutil" when using the interactive interpreter from within
@# this directory. @# this directory.
$(PYTHON) setup.py build_ext -i PYTHONWARNINGS=all $(PYTHON) setup.py build_ext -i
rm -rf tmp
$(PYTHON) -c "import psutil" # make sure it actually worked
# useful deps which are nice to have while developing / testing install: ## Install this package as current user in "edit" mode.
setup-dev-env: ${MAKE} build
python -c "import urllib2; \ PYTHONWARNINGS=all $(PYTHON) setup.py develop $(INSTALL_OPTS)
r = urllib2.urlopen('https://bootstrap.pypa.io/get-pip.py'); \ rm -rf tmp
open('/tmp/get-pip.py', 'w').write(r.read());"
$(PYTHON) /tmp/get-pip.py --user
rm /tmp/get-pip.py
$(PYTHON) -m pip install --user --upgrade pip
$(PYTHON) -m pip install --user --upgrade \
coverage \
flake8 \
ipaddress \
ipdb \
mock==1.0.1 \
nose \
pep8 \
pyflakes \
sphinx \
sphinx-pypi-upload \
unittest2 \
install: build uninstall: ## Uninstall this package via pip.
$(PYTHON) setup.py install --user
uninstall:
cd ..; $(PYTHON) -m pip uninstall -y -v psutil cd ..; $(PYTHON) -m pip uninstall -y -v psutil
test: install install-pip: ## Install pip (no-op if already installed).
$(PYTHON) $(TSCRIPT) $(PYTHON) -c \
"import sys, ssl, os, pkgutil, tempfile, atexit; \
sys.exit(0) if pkgutil.find_loader('pip') else None; \
pyexc = 'from urllib.request import urlopen' if sys.version_info[0] == 3 else 'from urllib2 import urlopen'; \
exec(pyexc); \
ctx = ssl._create_unverified_context() if hasattr(ssl, '_create_unverified_context') else None; \
kw = dict(context=ctx) if ctx else {}; \
req = urlopen('https://bootstrap.pypa.io/get-pip.py', **kw); \
data = req.read(); \
f = tempfile.NamedTemporaryFile(suffix='.py'); \
atexit.register(f.close); \
f.write(data); \
f.flush(); \
print('downloaded %s' % f.name); \
code = os.system('%s %s --user' % (sys.executable, f.name)); \
f.close(); \
sys.exit(code);"
test-process: install setup-dev-env: ## Install GIT hooks, pip, test deps (also upgrades them).
$(PYTHON) -m unittest -v test.test_psutil.TestProcess ${MAKE} install-git-hooks
${MAKE} install-pip
$(PYTHON) -m pip install $(INSTALL_OPTS) --upgrade pip
$(PYTHON) -m pip install $(INSTALL_OPTS) --upgrade $(DEPS)
test-system: install # ===================================================================
$(PYTHON) -m unittest -v test.test_psutil.TestSystemAPIs # Tests
# ===================================================================
test-memleaks: install test: ## Run all tests.
$(PYTHON) test/test_memory_leaks.py ${MAKE} install
$(TEST_PREFIX) $(PYTHON) $(TSCRIPT)
# Run a specific test by name; e.g. "make test-by-name disk_" will run test-process: ## Run process-related API tests.
# all test methods containing "disk_" in their name. ${MAKE} install
# Requires "pip install nose". $(TEST_PREFIX) $(PYTHON) -m unittest -v psutil.tests.test_process
test-by-name: install
@$(PYTHON) -m nose test/test_psutil.py test/_* --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS))
# Same as above but for test_memory_leaks.py script. test-system: ## Run system-related API tests.
test-memleaks-by-name: install ${MAKE} install
@$(PYTHON) -m nose test/test_memory_leaks.py --nocapture -v -m $(filter-out $@,$(MAKECMDGOALS)) $(TEST_PREFIX) $(PYTHON) -m unittest -v psutil.tests.test_system
coverage: install test-misc: ## Run miscellaneous tests.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_misc.py
test-unicode: ## Test APIs dealing with strings.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_unicode.py
test-contracts: ## APIs sanity tests.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_contracts.py
test-connections: ## Test net_connections() and Process.connections().
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_connections.py
test-posix: ## POSIX specific tests.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_posix.py
test-platform: ## Run specific platform tests only.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_`$(PYTHON) -c 'import psutil; print([x.lower() for x in ("LINUX", "BSD", "OSX", "SUNOS", "WINDOWS", "AIX") if getattr(psutil, x)][0])'`.py
test-memleaks: ## Memory leak tests.
${MAKE} install
$(TEST_PREFIX) $(PYTHON) psutil/tests/test_memory_leaks.py
test-by-name: ## e.g. make test-by-name ARGS=psutil.tests.test_system.TestSystemAPIs
${MAKE} install
@$(TEST_PREFIX) $(PYTHON) -m unittest -v $(ARGS)
test-coverage: ## Run test coverage.
${MAKE} install
# Note: coverage options are controlled by .coveragerc file # Note: coverage options are controlled by .coveragerc file
rm -rf .coverage htmlcov rm -rf .coverage htmlcov
$(PYTHON) -m coverage run $(TSCRIPT) $(TEST_PREFIX) $(PYTHON) -m coverage run $(TSCRIPT)
$(PYTHON) -m coverage report $(PYTHON) -m coverage report
@echo "writing results to htmlcov/index.html" @echo "writing results to htmlcov/index.html"
$(PYTHON) -m coverage html $(PYTHON) -m coverage html
$(PYTHON) -m webbrowser -t htmlcov/index.html $(PYTHON) -m webbrowser -t htmlcov/index.html
pep8: # ===================================================================
# Linters
# ===================================================================
pep8: ## PEP8 linter.
@git ls-files | grep \\.py$ | xargs $(PYTHON) -m pep8 @git ls-files | grep \\.py$ | xargs $(PYTHON) -m pep8
pyflakes: pyflakes: ## Pyflakes linter.
@export PYFLAKES_NODOCTEST=1 && \ @export PYFLAKES_NODOCTEST=1 && \
git ls-files | grep \\.py$ | xargs $(PYTHON) -m pyflakes git ls-files | grep \\.py$ | xargs $(PYTHON) -m pyflakes
flake8: flake8: ## flake8 linter.
@git ls-files | grep \\.py$ | xargs $(PYTHON) -m flake8 @git ls-files | grep \\.py$ | xargs $(PYTHON) -m flake8
# Upload source tarball on https://pypi.python.org/pypi/psutil. # ===================================================================
upload-src: clean # GIT
$(PYTHON) setup.py sdist upload # ===================================================================
# Build and upload doc on https://pythonhosted.org/psutil/. git-tag-release: ## Git-tag a new release.
# Requires "pip install sphinx-pypi-upload".
upload-doc:
cd docs; make html
$(PYTHON) setup.py upload_sphinx --upload-dir=docs/_build/html
# git-tag a new release
git-tag-release:
git tag -a release-`python -c "import setup; print(setup.get_version())"` -m `git rev-list HEAD --count`:`git rev-parse --short HEAD` git tag -a release-`python -c "import setup; print(setup.get_version())"` -m `git rev-list HEAD --count`:`git rev-parse --short HEAD`
echo "done; now run 'git push --follow-tags' to push the new tag on the remote repo" git push --follow-tags
# install GIT pre-commit hook install-git-hooks: ## Install GIT pre-commit hook.
install-git-hooks:
ln -sf ../../.git-pre-commit .git/hooks/pre-commit ln -sf ../../.git-pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit chmod +x .git/hooks/pre-commit
# ===================================================================
# Distribution
# ===================================================================
# --- create
sdist: ## Create tar.gz source distribution.
${MAKE} generate-manifest
$(PYTHON) setup.py sdist
wheel: ## Generate wheel.
$(PYTHON) setup.py bdist_wheel
win-download-wheels: ## Download wheels hosted on appveyor.
$(TEST_PREFIX) $(PYTHON) scripts/internal/download_exes.py --user giampaolo --project psutil
# --- upload
upload-src: ## Upload source tarball on https://pypi.python.org/pypi/psutil.
${MAKE} sdist
$(PYTHON) setup.py sdist upload
upload-win-wheels: ## Upload wheels in dist/* directory on PYPI.
$(PYTHON) -m twine upload dist/*.whl
# --- others
pre-release: ## Check if we're ready to produce a new release.
rm -rf dist
${MAKE} install
${MAKE} generate-manifest
git diff MANIFEST.in > /dev/null # ...otherwise 'git diff-index HEAD' will complain
${MAKE} win-download-wheels
${MAKE} sdist
$(PYTHON) -c \
"from psutil import __version__ as ver; \
doc = open('docs/index.rst').read(); \
history = open('HISTORY.rst').read(); \
assert ver in doc, '%r not in docs/index.rst' % ver; \
assert ver in history, '%r not in HISTORY.rst' % ver; \
assert 'XXXX' not in history, 'XXXX in HISTORY.rst';"
$(PYTHON) -c "import subprocess, sys; out = subprocess.check_output('git diff --quiet && git diff --cached --quiet', shell=True).strip(); sys.exit('there are uncommitted changes:\n%s' % out) if out else 0 ;"
release: ## Create a release (down/uploads tar.gz, wheels, git tag release).
${MAKE} pre-release
$(PYTHON) -m twine upload dist/* # upload tar.gz and Windows wheels on PYPI
${MAKE} git-tag-release
print-announce: ## Print announce of new release.
@$(TEST_PREFIX) $(PYTHON) scripts/internal/print_announce.py
print-timeline: ## Print releases' timeline.
@$(TEST_PREFIX) $(PYTHON) scripts/internal/print_timeline.py
check-manifest: ## Inspect MANIFEST.in file.
$(PYTHON) -m check_manifest -v $(ARGS)
generate-manifest: ## Generates MANIFEST.in file.
$(PYTHON) scripts/internal/generate_manifest.py > MANIFEST.in
# ===================================================================
# Misc
# ===================================================================
grep-todos: ## Look for TODOs in the source files.
git grep -EIn "TODO|FIXME|XXX"
bench-oneshot: ## Benchmarks for oneshot() ctx manager (see #799).
${MAKE} install
$(TEST_PREFIX) $(PYTHON) scripts/internal/bench_oneshot.py
bench-oneshot-2: ## Same as above but using perf module (supposed to be more precise)
${MAKE} install
$(TEST_PREFIX) $(PYTHON) scripts/internal/bench_oneshot_2.py
check-broken-links: ## Look for broken links in source files.
git ls-files | xargs $(PYTHON) -Wa scripts/internal/check_broken_links.py
help: ## Display callable targets.
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

365
third_party/python/psutil/PKG-INFO поставляемый
Просмотреть файл

@ -1,28 +1,29 @@
Metadata-Version: 1.1 Metadata-Version: 1.1
Name: psutil Name: psutil
Version: 3.1.1 Version: 5.4.3
Summary: psutil is a cross-platform library for retrieving information onrunning processes and system utilization (CPU, memory, disks, network)in Python. Summary: Cross-platform lib for process and system monitoring in Python.
Home-page: https://github.com/giampaolo/psutil Home-page: https://github.com/giampaolo/psutil
Author: Giampaolo Rodola Author: Giampaolo Rodola
Author-email: g.rodola <at> gmail <dot> com Author-email: g.rodola@gmail.com
License: BSD License: BSD
Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg Description-Content-Type: UNKNOWN
:target: https://pypi.python.org/pypi/psutil#downloads Description: .. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20OSX
:alt: Downloads this month
.. image:: https://api.travis-ci.org/giampaolo/psutil.png?branch=master
:target: https://travis-ci.org/giampaolo/psutil :target: https://travis-ci.org/giampaolo/psutil
:alt: Linux tests (Travis) :alt: Linux tests (Travis)
.. image:: https://ci.appveyor.com/api/projects/status/qdwvw7v1t915ywr5/branch/master?svg=true .. image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
:target: https://ci.appveyor.com/project/giampaolo/psutil :target: https://ci.appveyor.com/project/giampaolo/psutil
:alt: Windows tests (Appveyor) :alt: Windows tests (Appveyor)
.. image:: https://coveralls.io/repos/giampaolo/psutil/badge.svg?branch=master&service=github .. image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master :target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io) :alt: Test coverage (coverall.io)
.. image:: https://img.shields.io/pypi/v/psutil.svg .. image:: https://readthedocs.org/projects/psutil/badge/?version=latest
:target: http://psutil.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
:target: https://pypi.python.org/pypi/psutil/ :target: https://pypi.python.org/pypi/psutil/
:alt: Latest version :alt: Latest version
@ -30,10 +31,6 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://github.com/giampaolo/psutil/ :target: https://github.com/giampaolo/psutil/
:alt: Github stars :alt: Github stars
.. image:: https://img.shields.io/scrutinizer/g/giampaolo/psutil.svg
:target: https://scrutinizer-ci.com/g/giampaolo/psutil/
:alt: Code quality (scrutinizer-ci.com)
.. image:: https://img.shields.io/pypi/l/psutil.svg .. image:: https://img.shields.io/pypi/l/psutil.svg
:target: https://pypi.python.org/pypi/psutil/ :target: https://pypi.python.org/pypi/psutil/
:alt: License :alt: License
@ -43,8 +40,8 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
=========== ===========
- `Home page <https://github.com/giampaolo/psutil>`_ - `Home page <https://github.com/giampaolo/psutil>`_
- `Documentation <http://pythonhosted.org/psutil/>`_ - `Install <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
- `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_ - `Documentation <http://psutil.readthedocs.io>`_
- `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_ - `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_
- `Forum <http://groups.google.com/group/psutil/topics>`_ - `Forum <http://groups.google.com/group/psutil/topics>`_
- `Blog <http://grodola.blogspot.com/search/label/psutil>`_ - `Blog <http://grodola.blogspot.com/search/label/psutil>`_
@ -55,39 +52,70 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
Summary Summary
======= =======
psutil (python system and process utilities) is a cross-platform library for psutil (process and system utilities) is a cross-platform library for
retrieving information on **running processes** and **system utilization** retrieving information on **running processes** and **system utilization**
(CPU, memory, disks, network) in Python. It is useful mainly for **system (CPU, memory, disks, network, sensors) in Python.
monitoring**, **profiling and limiting process resources** and **management of It is useful mainly for **system monitoring**, **profiling and limiting process
running processes**. It implements many functionalities offered by command line resources** and **management of running processes**.
tools such as: ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice, It implements many functionalities offered by UNIX command line tools such as:
ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap. It currently supports ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice, ionice, iostat,
**Linux, Windows, OSX, FreeBSD** and **Sun Solaris**, both **32-bit** and iotop, uptime, pidof, tty, taskset, pmap.
**64-bit** architectures, with Python versions from **2.6 to 3.5** (users of psutil currently supports the following platforms:
Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
- **Linux**
- **Windows**
- **OSX**,
- **FreeBSD, OpenBSD**, **NetBSD**
- **Sun Solaris**
- **AIX**
...both **32-bit** and **64-bit** architectures, with Python
versions from **2.6 to 3.6**.
`PyPy <http://pypy.org/>`__ is also known to work. `PyPy <http://pypy.org/>`__ is also known to work.
==================== ====================
Example applications Example applications
==================== ====================
.. image:: http://psutil.googlecode.com/svn/wiki/images/top-thumb.png +------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
:target: http://psutil.googlecode.com/svn/wiki/images/top.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo-small.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/top-small.png |
:alt: top | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo.png | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/top.png |
+------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem-small.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap-small.png |
| :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem.png | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap.png |
+------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
.. image:: http://psutil.googlecode.com/svn/wiki/images/nettop-thumb.png Also see `scripts directory <https://github.com/giampaolo/psutil/tree/master/scripts>`__
:target: http://psutil.googlecode.com/svn/wiki/images/nettop.png and `doc recipes <http://psutil.readthedocs.io/#recipes/>`__.
:alt: nettop
.. image:: http://psutil.googlecode.com/svn/wiki/images/iotop-thumb.png =====================
:target: http://psutil.googlecode.com/svn/wiki/images/iotop.png Projects using psutil
:alt: iotop =====================
See also: At the time of writing psutil has roughly
`2.9 milion downloads <https://github.com/giampaolo/psutil/issues/1053#issuecomment-340166262>`__
per month and there are over
`6000 open source projects <https://libraries.io/pypi/psutil/dependent_repositories?page=1>`__
on github which depend from psutil.
Here's some I find particularly interesting:
* https://github.com/nicolargo/glances - https://github.com/facebook/osquery/
* https://github.com/google/grr - https://github.com/nicolargo/glances
* https://github.com/Jahaja/psdash - https://github.com/google/grr
- https://github.com/Jahaja/psdash
- https://github.com/ajenti/ajenti
- https://github.com/home-assistant/home-assistant/
========
Portings
========
- Go: https://github.com/shirou/gopsutil
- C: https://github.com/hamon-in/cpslib
- Node: https://github.com/christkv/node-psutil
- Rust: https://github.com/borntyping/rust-psutil
- Ruby: https://github.com/spacewander/posixpsutil
- Nim: https://github.com/johnscillieri/psutil-nim
============== ==============
Example usages Example usages
@ -116,7 +144,6 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
[7.0, 8.5, 2.4, 2.1] [7.0, 8.5, 2.4, 2.1]
[1.2, 9.0, 9.9, 7.2] [1.2, 9.0, 9.9, 7.2]
>>> >>>
>>>
>>> for x in range(3): >>> for x in range(3):
... psutil.cpu_times_percent(interval=1, percpu=False) ... psutil.cpu_times_percent(interval=1, percpu=False)
... ...
@ -129,14 +156,21 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
>>> psutil.cpu_count(logical=False) >>> psutil.cpu_count(logical=False)
2 2
>>> >>>
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
>>>
>>> psutil.cpu_freq()
scpufreq(current=931.42925, min=800.0, max=3500.0)
>>>
Memory Memory
====== ======
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.virtual_memory() >>> psutil.virtual_memory()
svmem(total=8374149120, available=2081050624, percent=75.1, used=8074080256, free=300068864, active=3294920704, inactive=1361616896, buffers=529895424, cached=1251086336) svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304)
>>> psutil.swap_memory() >>> psutil.swap_memory()
sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944) sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
>>> >>>
@ -146,6 +180,7 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.disk_partitions() >>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'), [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')] sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
@ -154,7 +189,7 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5) sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>> >>>
>>> psutil.disk_io_counters(perdisk=False) >>> psutil.disk_io_counters(perdisk=False)
sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568) sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568, read_merged_count=619166, write_merged_count=812396, busy_time=4523412)
>>> >>>
Network Network
@ -162,37 +197,62 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.net_io_counters(pernic=True) >>> psutil.net_io_counters(pernic=True)
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0), {'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)} 'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>> >>>
>>> psutil.net_connections() >>> psutil.net_connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254), [sconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987), sconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED', pid=None),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None) sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT', pid=None)
...] ...]
>>> >>>
>>> psutil.net_if_addrs() >>> psutil.net_if_addrs()
{'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'), {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None), snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')], snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'), 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None), snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]} snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>> >>>
>>> psutil.net_if_stats() >>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500), {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)} 'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
>>>
Sensors
=======
.. code-block:: python
>>> import psutil
>>> psutil.sensors_temperatures()
{'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 1', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 2', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 3', current=47.0, high=100.0, critical=100.0)]}
>>>
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
>>>
>>> psutil.sensors_battery()
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>>
Other system info Other system info
================= =================
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.users() >>> psutil.users()
[user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0), [suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)] suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
>>> >>>
>>> psutil.boot_time() >>> psutil.boot_time()
1365519115.0 1365519115.0
@ -205,12 +265,10 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
>>> import psutil >>> import psutil
>>> psutil.pids() >>> psutil.pids()
[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, [1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, 268, 1215, 1216, 1220, 1221, 1243, 1244,
268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355, 1301, 1601, 2237, 2355, 2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4263, 4282,
2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446,
4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 5167, 5234, 5235, 5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
>>> >>>
>>> p = psutil.Process(7055) >>> p = psutil.Process(7055)
>>> p.name() >>> p.name()
@ -222,6 +280,16 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
>>> p.cmdline() >>> p.cmdline()
['/usr/bin/python', 'main.py'] ['/usr/bin/python', 'main.py']
>>> >>>
>>> p.pid
7055
>>> p.ppid()
7054
>>> p.parent()
<psutil.Process(pid=7054, name='bash') at 140008329539408>
>>> p.children()
[<psutil.Process(pid=8031, name='python') at 14020832451977>,
<psutil.Process(pid=8044, name='python') at 19229444921932>]
>>>
>>> p.status() >>> p.status()
'running' 'running'
>>> p.username() >>> p.username()
@ -237,39 +305,41 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
pgids(real=1000, effective=1000, saved=1000) pgids(real=1000, effective=1000, saved=1000)
>>> >>>
>>> p.cpu_times() >>> p.cpu_times()
pcputimes(user=1.02, system=0.31) pcputimes(user=1.02, system=0.31, children_user=0.32, children_system=0.1)
>>> p.cpu_percent(interval=1.0) >>> p.cpu_percent(interval=1.0)
12.1 12.1
>>> p.cpu_affinity() >>> p.cpu_affinity()
[0, 1, 2, 3] [0, 1, 2, 3]
>>> p.cpu_affinity([0]) # set >>> p.cpu_affinity([0, 1]) # set
>>> >>> p.cpu_num()
>>> p.memory_percent() 1
0.63423
>>> >>>
>>> p.memory_info() >>> p.memory_info()
pmem(rss=7471104, vms=68513792) pmem(rss=10915840, vms=67608576, shared=3313664, text=2310144, lib=0, data=7262208, dirty=0)
>>> p.memory_info_ex() >>> p.memory_full_info() # "real" USS memory usage (Linux, OSX, Win only)
extmem(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0) pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
>>> p.memory_percent()
0.7823
>>> p.memory_maps() >>> p.memory_maps()
[pmmap_grouped(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0), [pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0), pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0), pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, rss=32768, size=2134016, pss=15360, shared_clean=24576, shared_dirty=0, private_clean=0, private_dirty=8192, referenced=24576, anonymous=8192, swap=0),
pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0), pmmap_grouped(path='[heap]', rss=32768, size=139264, pss=32768, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=32768, referenced=32768, anonymous=32768, swap=0),
pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0), pmmap_grouped(path='[stack]', rss=2465792, size=2494464, pss=2465792, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=2465792, referenced=2277376, anonymous=2465792, swap=0),
...] ...]
>>> >>>
>>> p.io_counters() >>> p.io_counters()
pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632) pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632, read_chars=456232, write_chars=517543)
>>> >>>
>>> p.open_files() >>> p.open_files()
[popenfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)] [popenfile(path='/home/giampaolo/svn/psutil/setup.py', fd=3, position=0, mode='r', flags=32768),
popenfile(path='/var/log/monitd', fd=4, position=235542, mode='a', flags=33793)]
>>> >>>
>>> p.connections() >>> p.connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'), [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'), pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING'),
pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'), pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED'),
pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')] pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT')]
>>> >>>
>>> p.num_threads() >>> p.num_threads()
4 4
@ -296,6 +366,15 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
>>> p.rlimit(psutil.RLIMIT_NOFILE) >>> p.rlimit(psutil.RLIMIT_NOFILE)
(5, 5) (5, 5)
>>> >>>
>>> p.environ()
{'LC_PAPER': 'it_IT.UTF-8', 'SHELL': '/bin/bash', 'GREP_OPTIONS': '--color=auto',
'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg', 'COLORTERM': 'gnome-terminal',
...}
>>>
>>> p.as_dict()
{'status': 'running', 'num_ctx_switches': pctxsw(voluntary=63, involuntary=1), 'pid': 5457, ...}
>>> p.is_running()
True
>>> p.suspend() >>> p.suspend()
>>> p.resume() >>> p.resume()
>>> >>>
@ -319,81 +398,87 @@ Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
.. code-block:: python .. code-block:: python
>>> for p in psutil.process_iter(): >>> import psutil
... print(p) >>> for proc in psutil.process_iter(attrs=['pid', 'name']):
... print(proc.info)
... ...
psutil.Process(pid=1, name='init') {'pid': 1, 'name': 'systemd'}
psutil.Process(pid=2, name='kthreadd') {'pid': 2, 'name': 'kthreadd'}
psutil.Process(pid=3, name='ksoftirqd/0') {'pid': 3, 'name': 'ksoftirqd/0'}
... ...
>>> >>>
>>> psutil.pid_exists(3)
True
>>>
>>> def on_terminate(proc): >>> def on_terminate(proc):
... print("process {} terminated".format(proc)) ... print("process {} terminated".format(proc))
... ...
>>> # waits for multiple processes to terminate >>> # waits for multiple processes to terminate
>>> gone, alive = psutil.wait_procs(procs_list, 3, callback=on_terminate) >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
>>> >>>
Popen wrapper:
.. code-block:: python
>>> import psutil
>>> from subprocess import PIPE
>>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
>>> p.name()
'python'
>>> p.username()
'giampaolo'
>>> p.communicate()
('hello\n', None)
>>> p.wait(timeout=2)
0
>>>
Windows services
================
.. code-block:: python
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
Other samples
=============
See `doc recipes <http://psutil.readthedocs.io/#recipes>`__.
====== ======
Donate Author
====== ======
psutil was created and is maintained by
`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__.
A lot of time and effort went into making psutil as it is right now. A lot of time and effort went into making psutil as it is right now.
If you feel psutil is useful to you or your business and want to support its future development please consider donating me (`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`_) some money. If you feel psutil is useful to you or your business and want to support its
I only ask for a small donation, but of course I appreciate any amount. future development please consider donating me
(`Giampaolo <http://grodola.blogspot.com/p/about.html>`__) some money.
.. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif .. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8 :target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
:alt: Donate via PayPal :alt: Donate via PayPal
Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <http://www.linkedin.com/in/grodola>`_. Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <https://www.linkedin.com/in/grodola>`_.
============ Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,pstree,monitoring,ulimit,prlimit,smem
Mailing list
============
http://groups.google.com/group/psutil/
========
Timeline
========
- 2015-07-15: `psutil-3.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.1.tar.gz>`_
- 2015-07-15: `psutil-3.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.0.tar.gz>`_
- 2015-06-18: `psutil-3.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.1.tar.gz>`_
- 2015-06-13: `psutil-3.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.0.tar.gz>`_
- 2015-02-02: `psutil-2.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.1.tar.gz>`_
- 2015-01-06: `psutil-2.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.0.tar.gz>`_
- 2014-09-26: `psutil-2.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz>`_
- 2014-09-21: `psutil-2.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.2.tar.gz>`_
- 2014-04-30: `psutil-2.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.1.tar.gz>`_
- 2014-04-08: `psutil-2.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.0.tar.gz>`_
- 2014-03-10: `psutil-2.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz>`_
- 2013-11-25: `psutil-1.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.1.tar.gz>`_
- 2013-11-20: `psutil-1.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.0.tar.gz>`_
- 2013-11-07: `psutil-1.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.3.tar.gz>`_
- 2013-10-22: `psutil-1.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.2.tar.gz>`_
- 2013-10-08: `psutil-1.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.1.tar.gz>`_
- 2013-09-28: `psutil-1.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.0.tar.gz>`_
- 2013-07-12: `psutil-1.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.1.tar.gz>`_
- 2013-07-10: `psutil-1.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.0.tar.gz>`_
- 2013-05-03: `psutil-0.7.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.1.tar.gz>`_
- 2013-04-12: `psutil-0.7.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.0.tar.gz>`_
- 2012-08-16: `psutil-0.6.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.1.tar.gz>`_
- 2012-08-13: `psutil-0.6.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.0.tar.gz>`_
- 2012-06-29: `psutil-0.5.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.1.tar.gz>`_
- 2012-06-27: `psutil-0.5.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.0.tar.gz>`_
- 2011-12-14: `psutil-0.4.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.1.tar.gz>`_
- 2011-10-29: `psutil-0.4.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.0.tar.gz>`_
- 2011-07-08: `psutil-0.3.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.3.0.tar.gz>`_
- 2011-03-20: `psutil-0.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.1.tar.gz>`_
- 2010-11-13: `psutil-0.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.0.tar.gz>`_
- 2010-03-02: `psutil-0.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.3.tar.gz>`_
- 2009-05-06: `psutil-0.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.2.tar.gz>`_
- 2009-03-06: `psutil-0.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.1.tar.gz>`_
- 2009-01-27: `psutil-0.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.0.tar.gz>`_
Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,pstree,monitoring,ulimit,prlimit
Platform: Platform Independent Platform: Platform Independent
Classifier: Development Status :: 5 - Production/Stable Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console Classifier: Environment :: Console
@ -407,6 +492,9 @@ Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
Classifier: Operating System :: Microsoft Classifier: Operating System :: Microsoft
Classifier: Operating System :: OS Independent Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: BSD :: FreeBSD Classifier: Operating System :: POSIX :: BSD :: FreeBSD
Classifier: Operating System :: POSIX :: BSD :: NetBSD
Classifier: Operating System :: POSIX :: BSD :: OpenBSD
Classifier: Operating System :: POSIX :: BSD
Classifier: Operating System :: POSIX :: Linux Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: POSIX :: SunOS/Solaris Classifier: Operating System :: POSIX :: SunOS/Solaris
Classifier: Operating System :: POSIX Classifier: Operating System :: POSIX
@ -415,11 +503,9 @@ Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python Classifier: Programming Language :: Python
@ -430,5 +516,6 @@ Classifier: Topic :: System :: Hardware
Classifier: Topic :: System :: Monitoring Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Networking :: Monitoring Classifier: Topic :: System :: Networking :: Monitoring
Classifier: Topic :: System :: Networking Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Operating System
Classifier: Topic :: System :: Systems Administration Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities Classifier: Topic :: Utilities

346
third_party/python/psutil/README.rst поставляемый
Просмотреть файл

@ -1,20 +1,20 @@
.. image:: https://img.shields.io/pypi/dm/psutil.svg .. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20OSX
:target: https://pypi.python.org/pypi/psutil#downloads
:alt: Downloads this month
.. image:: https://api.travis-ci.org/giampaolo/psutil.png?branch=master
:target: https://travis-ci.org/giampaolo/psutil :target: https://travis-ci.org/giampaolo/psutil
:alt: Linux tests (Travis) :alt: Linux tests (Travis)
.. image:: https://ci.appveyor.com/api/projects/status/qdwvw7v1t915ywr5/branch/master?svg=true .. image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
:target: https://ci.appveyor.com/project/giampaolo/psutil :target: https://ci.appveyor.com/project/giampaolo/psutil
:alt: Windows tests (Appveyor) :alt: Windows tests (Appveyor)
.. image:: https://coveralls.io/repos/giampaolo/psutil/badge.svg?branch=master&service=github .. image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master :target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io) :alt: Test coverage (coverall.io)
.. image:: https://img.shields.io/pypi/v/psutil.svg .. image:: https://readthedocs.org/projects/psutil/badge/?version=latest
:target: http://psutil.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
:target: https://pypi.python.org/pypi/psutil/ :target: https://pypi.python.org/pypi/psutil/
:alt: Latest version :alt: Latest version
@ -22,10 +22,6 @@
:target: https://github.com/giampaolo/psutil/ :target: https://github.com/giampaolo/psutil/
:alt: Github stars :alt: Github stars
.. image:: https://img.shields.io/scrutinizer/g/giampaolo/psutil.svg
:target: https://scrutinizer-ci.com/g/giampaolo/psutil/
:alt: Code quality (scrutinizer-ci.com)
.. image:: https://img.shields.io/pypi/l/psutil.svg .. image:: https://img.shields.io/pypi/l/psutil.svg
:target: https://pypi.python.org/pypi/psutil/ :target: https://pypi.python.org/pypi/psutil/
:alt: License :alt: License
@ -35,8 +31,8 @@ Quick links
=========== ===========
- `Home page <https://github.com/giampaolo/psutil>`_ - `Home page <https://github.com/giampaolo/psutil>`_
- `Documentation <http://pythonhosted.org/psutil/>`_ - `Install <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
- `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_ - `Documentation <http://psutil.readthedocs.io>`_
- `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_ - `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_
- `Forum <http://groups.google.com/group/psutil/topics>`_ - `Forum <http://groups.google.com/group/psutil/topics>`_
- `Blog <http://grodola.blogspot.com/search/label/psutil>`_ - `Blog <http://grodola.blogspot.com/search/label/psutil>`_
@ -47,39 +43,70 @@ Quick links
Summary Summary
======= =======
psutil (python system and process utilities) is a cross-platform library for psutil (process and system utilities) is a cross-platform library for
retrieving information on **running processes** and **system utilization** retrieving information on **running processes** and **system utilization**
(CPU, memory, disks, network) in Python. It is useful mainly for **system (CPU, memory, disks, network, sensors) in Python.
monitoring**, **profiling and limiting process resources** and **management of It is useful mainly for **system monitoring**, **profiling and limiting process
running processes**. It implements many functionalities offered by command line resources** and **management of running processes**.
tools such as: ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice, It implements many functionalities offered by UNIX command line tools such as:
ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap. It currently supports ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice, ionice, iostat,
**Linux, Windows, OSX, FreeBSD** and **Sun Solaris**, both **32-bit** and iotop, uptime, pidof, tty, taskset, pmap.
**64-bit** architectures, with Python versions from **2.6 to 3.5** (users of psutil currently supports the following platforms:
Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
- **Linux**
- **Windows**
- **OSX**,
- **FreeBSD, OpenBSD**, **NetBSD**
- **Sun Solaris**
- **AIX**
...both **32-bit** and **64-bit** architectures, with Python
versions from **2.6 to 3.6**.
`PyPy <http://pypy.org/>`__ is also known to work. `PyPy <http://pypy.org/>`__ is also known to work.
==================== ====================
Example applications Example applications
==================== ====================
.. image:: http://psutil.googlecode.com/svn/wiki/images/top-thumb.png +------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
:target: http://psutil.googlecode.com/svn/wiki/images/top.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo-small.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/top-small.png |
:alt: top | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo.png | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/top.png |
+------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
| .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem-small.png | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap-small.png |
| :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem.png | :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap.png |
+------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
.. image:: http://psutil.googlecode.com/svn/wiki/images/nettop-thumb.png Also see `scripts directory <https://github.com/giampaolo/psutil/tree/master/scripts>`__
:target: http://psutil.googlecode.com/svn/wiki/images/nettop.png and `doc recipes <http://psutil.readthedocs.io/#recipes/>`__.
:alt: nettop
.. image:: http://psutil.googlecode.com/svn/wiki/images/iotop-thumb.png =====================
:target: http://psutil.googlecode.com/svn/wiki/images/iotop.png Projects using psutil
:alt: iotop =====================
See also: At the time of writing psutil has roughly
`2.9 milion downloads <https://github.com/giampaolo/psutil/issues/1053#issuecomment-340166262>`__
per month and there are over
`6000 open source projects <https://libraries.io/pypi/psutil/dependent_repositories?page=1>`__
on github which depend from psutil.
Here's some I find particularly interesting:
* https://github.com/nicolargo/glances - https://github.com/facebook/osquery/
* https://github.com/google/grr - https://github.com/nicolargo/glances
* https://github.com/Jahaja/psdash - https://github.com/google/grr
- https://github.com/Jahaja/psdash
- https://github.com/ajenti/ajenti
- https://github.com/home-assistant/home-assistant/
========
Portings
========
- Go: https://github.com/shirou/gopsutil
- C: https://github.com/hamon-in/cpslib
- Node: https://github.com/christkv/node-psutil
- Rust: https://github.com/borntyping/rust-psutil
- Ruby: https://github.com/spacewander/posixpsutil
- Nim: https://github.com/johnscillieri/psutil-nim
============== ==============
Example usages Example usages
@ -108,7 +135,6 @@ CPU
[7.0, 8.5, 2.4, 2.1] [7.0, 8.5, 2.4, 2.1]
[1.2, 9.0, 9.9, 7.2] [1.2, 9.0, 9.9, 7.2]
>>> >>>
>>>
>>> for x in range(3): >>> for x in range(3):
... psutil.cpu_times_percent(interval=1, percpu=False) ... psutil.cpu_times_percent(interval=1, percpu=False)
... ...
@ -121,14 +147,21 @@ CPU
>>> psutil.cpu_count(logical=False) >>> psutil.cpu_count(logical=False)
2 2
>>> >>>
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
>>>
>>> psutil.cpu_freq()
scpufreq(current=931.42925, min=800.0, max=3500.0)
>>>
Memory Memory
====== ======
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.virtual_memory() >>> psutil.virtual_memory()
svmem(total=8374149120, available=2081050624, percent=75.1, used=8074080256, free=300068864, active=3294920704, inactive=1361616896, buffers=529895424, cached=1251086336) svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304)
>>> psutil.swap_memory() >>> psutil.swap_memory()
sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944) sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
>>> >>>
@ -138,6 +171,7 @@ Disks
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.disk_partitions() >>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'), [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')] sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
@ -146,7 +180,7 @@ Disks
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5) sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>> >>>
>>> psutil.disk_io_counters(perdisk=False) >>> psutil.disk_io_counters(perdisk=False)
sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568) sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568, read_merged_count=619166, write_merged_count=812396, busy_time=4523412)
>>> >>>
Network Network
@ -154,37 +188,62 @@ Network
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.net_io_counters(pernic=True) >>> psutil.net_io_counters(pernic=True)
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0), {'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)} 'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>> >>>
>>> psutil.net_connections() >>> psutil.net_connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254), [sconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987), sconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED', pid=None),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None) sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT', pid=None)
...] ...]
>>> >>>
>>> psutil.net_if_addrs() >>> psutil.net_if_addrs()
{'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'), {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None), snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')], snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'), 'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None), snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]} snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>> >>>
>>> psutil.net_if_stats() >>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500), {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)} 'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
>>>
Sensors
=======
.. code-block:: python
>>> import psutil
>>> psutil.sensors_temperatures()
{'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 1', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 2', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 3', current=47.0, high=100.0, critical=100.0)]}
>>>
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
>>>
>>> psutil.sensors_battery()
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>>
Other system info Other system info
================= =================
.. code-block:: python .. code-block:: python
>>> import psutil
>>> psutil.users() >>> psutil.users()
[user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0), [suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)] suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
>>> >>>
>>> psutil.boot_time() >>> psutil.boot_time()
1365519115.0 1365519115.0
@ -197,12 +256,10 @@ Process management
>>> import psutil >>> import psutil
>>> psutil.pids() >>> psutil.pids()
[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, [1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, 268, 1215, 1216, 1220, 1221, 1243, 1244,
268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355, 1301, 1601, 2237, 2355, 2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4263, 4282,
2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446,
4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 5167, 5234, 5235, 5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
>>> >>>
>>> p = psutil.Process(7055) >>> p = psutil.Process(7055)
>>> p.name() >>> p.name()
@ -214,6 +271,16 @@ Process management
>>> p.cmdline() >>> p.cmdline()
['/usr/bin/python', 'main.py'] ['/usr/bin/python', 'main.py']
>>> >>>
>>> p.pid
7055
>>> p.ppid()
7054
>>> p.parent()
<psutil.Process(pid=7054, name='bash') at 140008329539408>
>>> p.children()
[<psutil.Process(pid=8031, name='python') at 14020832451977>,
<psutil.Process(pid=8044, name='python') at 19229444921932>]
>>>
>>> p.status() >>> p.status()
'running' 'running'
>>> p.username() >>> p.username()
@ -229,39 +296,41 @@ Process management
pgids(real=1000, effective=1000, saved=1000) pgids(real=1000, effective=1000, saved=1000)
>>> >>>
>>> p.cpu_times() >>> p.cpu_times()
pcputimes(user=1.02, system=0.31) pcputimes(user=1.02, system=0.31, children_user=0.32, children_system=0.1)
>>> p.cpu_percent(interval=1.0) >>> p.cpu_percent(interval=1.0)
12.1 12.1
>>> p.cpu_affinity() >>> p.cpu_affinity()
[0, 1, 2, 3] [0, 1, 2, 3]
>>> p.cpu_affinity([0]) # set >>> p.cpu_affinity([0, 1]) # set
>>> >>> p.cpu_num()
>>> p.memory_percent() 1
0.63423
>>> >>>
>>> p.memory_info() >>> p.memory_info()
pmem(rss=7471104, vms=68513792) pmem(rss=10915840, vms=67608576, shared=3313664, text=2310144, lib=0, data=7262208, dirty=0)
>>> p.memory_info_ex() >>> p.memory_full_info() # "real" USS memory usage (Linux, OSX, Win only)
extmem(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0) pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
>>> p.memory_percent()
0.7823
>>> p.memory_maps() >>> p.memory_maps()
[pmmap_grouped(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0), [pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0), pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0), pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, rss=32768, size=2134016, pss=15360, shared_clean=24576, shared_dirty=0, private_clean=0, private_dirty=8192, referenced=24576, anonymous=8192, swap=0),
pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0), pmmap_grouped(path='[heap]', rss=32768, size=139264, pss=32768, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=32768, referenced=32768, anonymous=32768, swap=0),
pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0), pmmap_grouped(path='[stack]', rss=2465792, size=2494464, pss=2465792, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=2465792, referenced=2277376, anonymous=2465792, swap=0),
...] ...]
>>> >>>
>>> p.io_counters() >>> p.io_counters()
pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632) pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632, read_chars=456232, write_chars=517543)
>>> >>>
>>> p.open_files() >>> p.open_files()
[popenfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)] [popenfile(path='/home/giampaolo/svn/psutil/setup.py', fd=3, position=0, mode='r', flags=32768),
popenfile(path='/var/log/monitd', fd=4, position=235542, mode='a', flags=33793)]
>>> >>>
>>> p.connections() >>> p.connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'), [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'), pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING'),
pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'), pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED'),
pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')] pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT')]
>>> >>>
>>> p.num_threads() >>> p.num_threads()
4 4
@ -288,6 +357,15 @@ Process management
>>> p.rlimit(psutil.RLIMIT_NOFILE) >>> p.rlimit(psutil.RLIMIT_NOFILE)
(5, 5) (5, 5)
>>> >>>
>>> p.environ()
{'LC_PAPER': 'it_IT.UTF-8', 'SHELL': '/bin/bash', 'GREP_OPTIONS': '--color=auto',
'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg', 'COLORTERM': 'gnome-terminal',
...}
>>>
>>> p.as_dict()
{'status': 'running', 'num_ctx_switches': pctxsw(voluntary=63, involuntary=1), 'pid': 5457, ...}
>>> p.is_running()
True
>>> p.suspend() >>> p.suspend()
>>> p.resume() >>> p.resume()
>>> >>>
@ -311,76 +389,82 @@ Further process APIs
.. code-block:: python .. code-block:: python
>>> for p in psutil.process_iter(): >>> import psutil
... print(p) >>> for proc in psutil.process_iter(attrs=['pid', 'name']):
... print(proc.info)
... ...
psutil.Process(pid=1, name='init') {'pid': 1, 'name': 'systemd'}
psutil.Process(pid=2, name='kthreadd') {'pid': 2, 'name': 'kthreadd'}
psutil.Process(pid=3, name='ksoftirqd/0') {'pid': 3, 'name': 'ksoftirqd/0'}
... ...
>>> >>>
>>> psutil.pid_exists(3)
True
>>>
>>> def on_terminate(proc): >>> def on_terminate(proc):
... print("process {} terminated".format(proc)) ... print("process {} terminated".format(proc))
... ...
>>> # waits for multiple processes to terminate >>> # waits for multiple processes to terminate
>>> gone, alive = psutil.wait_procs(procs_list, 3, callback=on_terminate) >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
>>> >>>
Popen wrapper:
.. code-block:: python
>>> import psutil
>>> from subprocess import PIPE
>>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
>>> p.name()
'python'
>>> p.username()
'giampaolo'
>>> p.communicate()
('hello\n', None)
>>> p.wait(timeout=2)
0
>>>
Windows services
================
.. code-block:: python
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
Other samples
=============
See `doc recipes <http://psutil.readthedocs.io/#recipes>`__.
====== ======
Donate Author
====== ======
psutil was created and is maintained by
`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__.
A lot of time and effort went into making psutil as it is right now. A lot of time and effort went into making psutil as it is right now.
If you feel psutil is useful to you or your business and want to support its future development please consider donating me (`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`_) some money. If you feel psutil is useful to you or your business and want to support its
I only ask for a small donation, but of course I appreciate any amount. future development please consider donating me
(`Giampaolo <http://grodola.blogspot.com/p/about.html>`__) some money.
.. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif .. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8 :target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
:alt: Donate via PayPal :alt: Donate via PayPal
Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <http://www.linkedin.com/in/grodola>`_. Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <https://www.linkedin.com/in/grodola>`_.
============
Mailing list
============
http://groups.google.com/group/psutil/
========
Timeline
========
- 2015-07-15: `psutil-3.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.1.tar.gz>`_
- 2015-07-15: `psutil-3.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.0.tar.gz>`_
- 2015-06-18: `psutil-3.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.1.tar.gz>`_
- 2015-06-13: `psutil-3.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.0.tar.gz>`_
- 2015-02-02: `psutil-2.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.1.tar.gz>`_
- 2015-01-06: `psutil-2.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.0.tar.gz>`_
- 2014-09-26: `psutil-2.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz>`_
- 2014-09-21: `psutil-2.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.2.tar.gz>`_
- 2014-04-30: `psutil-2.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.1.tar.gz>`_
- 2014-04-08: `psutil-2.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.0.tar.gz>`_
- 2014-03-10: `psutil-2.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz>`_
- 2013-11-25: `psutil-1.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.1.tar.gz>`_
- 2013-11-20: `psutil-1.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.0.tar.gz>`_
- 2013-11-07: `psutil-1.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.3.tar.gz>`_
- 2013-10-22: `psutil-1.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.2.tar.gz>`_
- 2013-10-08: `psutil-1.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.1.tar.gz>`_
- 2013-09-28: `psutil-1.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.0.tar.gz>`_
- 2013-07-12: `psutil-1.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.1.tar.gz>`_
- 2013-07-10: `psutil-1.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.0.tar.gz>`_
- 2013-05-03: `psutil-0.7.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.1.tar.gz>`_
- 2013-04-12: `psutil-0.7.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.0.tar.gz>`_
- 2012-08-16: `psutil-0.6.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.1.tar.gz>`_
- 2012-08-13: `psutil-0.6.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.0.tar.gz>`_
- 2012-06-29: `psutil-0.5.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.1.tar.gz>`_
- 2012-06-27: `psutil-0.5.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.0.tar.gz>`_
- 2011-12-14: `psutil-0.4.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.1.tar.gz>`_
- 2011-10-29: `psutil-0.4.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.0.tar.gz>`_
- 2011-07-08: `psutil-0.3.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.3.0.tar.gz>`_
- 2011-03-20: `psutil-0.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.1.tar.gz>`_
- 2010-11-13: `psutil-0.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.0.tar.gz>`_
- 2010-03-02: `psutil-0.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.3.tar.gz>`_
- 2009-05-06: `psutil-0.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.2.tar.gz>`_
- 2009-03-06: `psutil-0.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.1.tar.gz>`_
- 2009-01-27: `psutil-0.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.0.tar.gz>`_

167
third_party/python/psutil/TODO поставляемый
Просмотреть файл

@ -1,167 +0,0 @@
TODO
====
A collection of ideas and notes about stuff to implement in future versions.
"#NNN" occurrences refer to bug tracker issues at:
https://github.com/giampaolo/psutil/issues
HIGHER PRIORITY
===============
* OpenBSD support.
* #371: CPU temperature (apparently OSX and Linux only; on Linux it requires
lm-sensors lib).
* #269: expose network ifaces RX/TW queues. This should probably go into
net_if_stats(). Figure out on what platforms this is supported:
Linux: yes
Others: ?
* Process.threads(): thread names; patch for OSX available at:
https://code.google.com/p/plcrashreporter/issues/detail?id=65
* Asynchronous psutil.Popen (see http://bugs.python.org/issue1191964)
* (Windows) fall back on using WMIC for Process methods returning AccessDenied
* #613: thread names.
* #604: emulate os.getloadavg() on Windows
* #269: NIC rx/tx queue.
LOWER PRIORITY
==============
* #355: Android support.
* #276: GNU/Hurd support.
* #429: NetBSD support.
* DragonFlyBSD support?
* AIX support?
* examples/taskmgr-gui.py (using tk).
* system-wide number of open file descriptors:
* https://jira.hyperic.com/browse/SIGAR-30
* http://www.netadmintools.com/part295.html
* Number of system threads.
* Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684824(v=vs.85).aspx
* #357: what CPU a process is on.
* Doc / wiki which compares similarities between UNIX cli tools and psutil.
Example:
df -a -> psutil.disk_partitions
lsof -> psutil.Process.open_files() and psutil.Process.open_connections()
killall-> (actual script)
tty -> psutil.Process.terminal()
who -> psutil.users()
DEBATABLE
=========
* psutil.proc_tree() something which obtains a {pid:ppid, ...} dict for
all running processes in one shot. This can be factored out from
Process.children() and exposed as a first class function.
PROS: on Windows we can take advantage of _psutil_windows.ppid_map()
which is faster than iterating over all pids and calling ppid().
CONS: examples/pstree.py shows this can be easily done in the user code
so maybe it's not worth the addition.
* advanced cmdline interface exposing the whole API and providing different
kind of outputs (e.g. pprinted, colorized, json).
* [Linux]: process cgroups (http://en.wikipedia.org/wiki/Cgroups). They look
similar to prlimit() in terms of functionality but uglier (they should allow
limiting per-process network IO resources though, which is great). Needs
further reading.
* Should we expose OS constants (psutil.WINDOWS, psutil.OSX etc.)?
* Python 3.3. exposed different sched.h functions:
http://docs.python.org/dev/whatsnew/3.3.html#os
http://bugs.python.org/issue12655
http://docs.python.org/dev/library/os.html#interface-to-the-scheduler
It might be worth to take a look and figure out whether we can include some
of those in psutil.
Also, we can probably reimplement wait_pid() on POSIX which is currently
implemented as a busy-loop.
* Certain systems provide CPU times about process children. On those systems
Process.cpu_times() might return a (user, system, user_children,
system_children) ntuple.
* Linux: /proc/{PID}/stat
* Solaris: pr_cutime and pr_cstime
* FreeBSD: none
* OSX: none
* Windows: none
* ...also, os.times() provides 'elapsed' times as well.
* ...also Linux provides guest_time and cguest_time.
* Enrich exception classes hierarchy on Python >= 3.3 / post PEP-3151 so that:
- NoSuchProcess inherits from ProcessLookupError
- AccessDenied inherits from PermissionError
- TimeoutExpired inherits from TimeoutError (debatable)
See: http://docs.python.org/3/library/exceptions.html#os-exceptions
* Process.threads() might grow an extra "id" parameter so that it can be
used as such:
>>> p = psutil.Process(os.getpid())
>>> p.threads(id=psutil.current_thread_id())
thread(id=2539, user_time=0.03, system_time=0.02)
>>>
Note: this leads to questions such as "should we have a custom NoSuchThread
exception? Also see issue #418.
Note #2: this would work with os.getpid() only.
psutil.current_thread_id() might be desirable as per issue #418 though.
* should psutil.TimeoutExpired exception have a 'msg' kwarg similar to
NoSuchProcess and AccessDenied? Not that we need it, but currently we
cannot raise a TimeoutExpired exception with a specific error string.
* process_iter() might grow an "attrs" parameter similar to Process.as_dict()
invoke the necessary methods and include the results into a "cache"
attribute attached to the returned Process instances so that one can avoid
catching NSP and AccessDenied:
for p in process_iter(attrs=['cpu_percent']):
print(p.cache['cpu_percent'])
This also leads questions as whether we should introduce a sorting order.
* round Process.memory_percent() result?
* #550: number of threads per core.
* Have psutil.Process().cpu_affinity([]) be an alias for "all CPUs"?
COMPATIBILITY BREAKAGE
======================
Removals (will likely happen in 2.2):
* (S) psutil.Process.nice (deprecated in 0.5.0)
* (S) get_process_list (deprecated in 0.5.0)
* (S) psutil.*mem* functions (deprecated in 0.3.0 and 0.6.0)
* (M) psutil.network_io_counters (deprecated in 1.0.0)
* (M) local_address and remote_address Process.connection() namedtuple fields
(deprecated in 1.0.0)
REJECTED IDEAS
==============
STUB

65
third_party/python/psutil/docs/Makefile поставляемый
Просмотреть файл

@ -2,16 +2,12 @@
# #
# You can set these variables from the command line. # You can set these variables from the command line.
PYTHON = python
SPHINXOPTS = SPHINXOPTS =
SPHINXBUILD = sphinx-build SPHINXBUILD = $(PYTHON) -m sphinx
PAPER = PAPER =
BUILDDIR = _build BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables. # Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter PAPEROPT_letter = -D latex_paper_size=letter
@ -19,8 +15,7 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others # the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext .PHONY: help
help: help:
@echo "Please use \`make <target>' where <target> is one of" @echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files" @echo " html to make standalone HTML files"
@ -30,8 +25,10 @@ help:
@echo " json to make JSON files" @echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project" @echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project" @echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project" @echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub" @echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@ -45,41 +42,51 @@ help:
@echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity" @echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean: clean:
rm -rf $(BUILDDIR) rm -rf $(BUILDDIR)
.PHONY: html
html: html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo @echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html." @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml: dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo @echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml: singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo @echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle: pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo @echo
@echo "Build finished; now you can process the pickle files." @echo "Build finished; now you can process the pickle files."
.PHONY: json
json: json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo @echo
@echo "Build finished; now you can process the JSON files." @echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp: htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo @echo
@echo "Build finished; now you can run HTML Help Workshop with the" \ @echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp." ".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp: qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo @echo
@ -89,6 +96,16 @@ qthelp:
@echo "To view the help file:" @echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/psutil.qhc" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/psutil.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp: devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo @echo
@ -98,11 +115,19 @@ devhelp:
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/psutil" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/psutil"
@echo "# devhelp" @echo "# devhelp"
.PHONY: epub
epub: epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo @echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub." @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex: latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo @echo
@ -110,28 +135,33 @@ latex:
@echo "Run \`make' in that directory to run these through (pdf)latex" \ @echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)." "(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf: latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..." @echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf $(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja: latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..." @echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text: text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo @echo
@echo "Build finished. The text files are in $(BUILDDIR)/text." @echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man: man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo @echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man." @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo: texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo @echo
@ -139,39 +169,58 @@ texinfo:
@echo "Run \`make' in that directory to run these through makeinfo" \ @echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)." "(use \`make info' here to do that automatically)."
.PHONY: info
info: info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..." @echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext: gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo @echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes: changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo @echo
@echo "The overview file is in $(BUILDDIR)/changes." @echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck: linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo @echo
@echo "Link check complete; look for any errors in the above output " \ @echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt." "or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest: doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \ @echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt." "results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml: xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo @echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml." @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml: pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo @echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."

4
third_party/python/psutil/docs/README поставляемый
Просмотреть файл

@ -3,7 +3,7 @@ About
This directory contains the reStructuredText (reST) sources to the psutil This directory contains the reStructuredText (reST) sources to the psutil
documentation. You don't need to build them yourself, prebuilt versions are documentation. You don't need to build them yourself, prebuilt versions are
available at https://pythonhosted.org/psutil/. available at http://psutil.readthedocs.io.
In case you want, you need to install sphinx first: In case you want, you need to install sphinx first:
$ pip install sphinx $ pip install sphinx
@ -12,4 +12,4 @@ Then run:
$ make html $ make html
You'll then have an HTML version of the doc at _build/html/index.html. You'll then have an HTML version of the doc at _build/html/index.html.

518
third_party/python/psutil/docs/_static/css/custom.css поставляемый Normal file
Просмотреть файл

@ -0,0 +1,518 @@
.wy-nav-content {
max-width: 100% !important;
padding: 15px !important;
}
.rst-content dl:not(.docutils) {
margin: 0px 0px 0px 0px;
}
.data dd {
margin-bottom: 0px !important;
}
.data .descname {
border-right:10px !important;
}
.local-toc li ul li{
padding-left: 20px !important;
}
.function .descclassname {
font-weight: normal !important;
}
.class .descclassname {
font-weight: normal !important;
}
.admonition.warning {
padding-top: 2px !important;
padding-bottom: 2px !important;
}
.admonition.note {
padding-top: 2px !important;
padding-bottom: 2px !important;
}
.rst-content dl:not(.docutils) dt {
color: #555;
}
.sig-paren {
padding-left: 2px;
padding-right: 2px;
}
h1, h2, h3 {
background: #eee;
padding: 5px;
border-bottom: 1px solid #ccc;
}
h1 {
font-size: 35px;
}
.admonition.warning {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.admonition.warning p {
margin-bottom: 5px !important;
}
.admonition.note {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
.admonition.note p {
margin-bottom: 5px !important;
backround-color: rgb(238, 255, 204) !important;
}
.codeblock div[class^='highlight'], pre.literal-block div[class^='highlight'], .rst-content .literal-block div[class^='highlight'], div[class^='highlight'] div[class^='highlight'] {
background-color: #eeffcc !important;
}
.highlight .hll {
background-color: #ffffcc
}
.highlight {
background: #eeffcc;
}
.highlight-default, .highlight-python {
border-radius: 3px !important;
border: 1px solid #ac9 !important;
}
.highlight .c {
color: #408090;
font-style: italic
}
.wy-side-nav-search {
background-color: grey !important
}
.highlight {
border-radius: 3px !important;
}
div.highlight-default {
margin-bottom: 10px !important;
}
pre {
padding: 5px !important;
}
/* ================================================================== */
/* Warnings and info boxes like python doc */
/* ================================================================== */
div.admonition {
margin-top: 10px !important;
margin-bottom: 10px !important;
}
div.warning {
background-color: #ffe4e4 !important;
border: 1px solid #f66 !important;
border-radius: 3px !important;
}
div.note {
background-color: #eee !important;
border: 1px solid #ccc !important;
border-radius: 3px !important;
}
div.admonition p.admonition-title + p {
display: inline !important;
}
p.admonition-title {
display: inline !important;
background: none !important;
color: black !important;
}
p.admonition-title:after {
content: ":" !important;
}
div.body div.admonition, div.body div.impl-detail {
}
.fa-exclamation-circle:before, .wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, .wy-inline-validate.wy-inline-validate-info .wy-input-context:before, .rst-content .admonition-title:before {
display: none !important;
}
.note code {
background: #d6d6d6 !important;
}
/* ================================================================== */
/* Syntax highlight like Python doc.
/* ================================================================== */
/* Comment */
.highlight .err {
border: 1px solid #FF0000
}
/* Error */
.highlight .k {
color: #007020;
font-weight: bold
}
/* Keyword */
.highlight .o {
color: #666666
}
/* Operator */
.highlight .ch {
color: #408090;
font-style: italic
}
/* Comment.Hashbang */
.highlight .cm {
color: #408090;
font-style: italic
}
/* Comment.Multiline */
.highlight .cp {
color: #007020
}
/* Comment.Preproc */
.highlight .cpf {
color: #408090;
font-style: italic
}
/* Comment.PreprocFile */
.highlight .c1 {
color: #408090;
font-style: italic
}
/* Comment.Single */
.highlight .cs {
color: #408090;
background-color: #fff0f0
}
/* Comment.Special */
.highlight .gd {
color: #A00000
}
/* Generic.Deleted */
.highlight .ge {
font-style: italic
}
/* Generic.Emph */
.highlight .gr {
color: #FF0000
}
/* Generic.Error */
.highlight .gh {
color: #000080;
font-weight: bold
}
/* Generic.Heading */
.highlight .gi {
color: #00A000
}
/* Generic.Inserted */
.highlight .go {
color: #333333
}
/* Generic.Output */
.highlight .gp {
color: #c65d09;
font-weight: bold
}
/* Generic.Prompt */
.highlight .gs {
font-weight: bold
}
/* Generic.Strong */
.highlight .gu {
color: #800080;
font-weight: bold
}
/* Generic.Subheading */
.highlight .gt {
color: #0044DD
}
/* Generic.Traceback */
.highlight .kc {
color: #007020;
font-weight: bold
}
/* Keyword.Constant */
.highlight .kd {
color: #007020;
font-weight: bold
}
/* Keyword.Declaration */
.highlight .kn {
color: #007020;
font-weight: bold
}
/* Keyword.Namespace */
.highlight .kp {
color: #007020
}
/* Keyword.Pseudo */
.highlight .kr {
color: #007020;
font-weight: bold
}
/* Keyword.Reserved */
.highlight .kt {
color: #902000
}
/* Keyword.Type */
.highlight .m {
color: #208050
}
/* Literal.Number */
.highlight .s {
color: #4070a0
}
/* Literal.String */
.highlight .na {
color: #4070a0
}
/* Name.Attribute */
.highlight .nb {
color: #007020
}
/* Name.Builtin */
.highlight .nc {
color: #0e84b5;
font-weight: bold
}
/* Name.Class */
.highlight .no {
color: #60add5
}
/* Name.Constant */
.highlight .nd {
color: #555555;
font-weight: bold
}
/* Name.Decorator */
.highlight .ni {
color: #d55537;
font-weight: bold
}
/* Name.Entity */
.highlight .ne {
color: #007020
}
/* Name.Exception */
.highlight .nf {
color: #06287e
}
/* Name.Function */
.highlight .nl {
color: #002070;
font-weight: bold
}
/* Name.Label */
.highlight .nn {
color: #0e84b5;
font-weight: bold
}
/* Name.Namespace */
.highlight .nt {
color: #062873;
font-weight: bold
}
/* Name.Tag */
.highlight .nv {
color: #bb60d5
}
/* Name.Variable */
.highlight .ow {
color: #007020;
font-weight: bold
}
/* Operator.Word */
.highlight .w {
color: #bbbbbb
}
/* Text.Whitespace */
.highlight .mb {
color: #208050
}
/* Literal.Number.Bin */
.highlight .mf {
color: #208050
}
/* Literal.Number.Float */
.highlight .mh {
color: #208050
}
/* Literal.Number.Hex */
.highlight .mi {
color: #208050
}
/* Literal.Number.Integer */
.highlight .mo {
color: #208050
}
/* Literal.Number.Oct */
.highlight .sa {
color: #4070a0
}
/* Literal.String.Affix */
.highlight .sb {
color: #4070a0
}
/* Literal.String.Backtick */
.highlight .sc {
color: #4070a0
}
/* Literal.String.Char */
.highlight .dl {
color: #4070a0
}
/* Literal.String.Delimiter */
.highlight .sd {
color: #4070a0;
font-style: italic
}
/* Literal.String.Doc */
.highlight .s2 {
color: #4070a0
}
/* Literal.String.Double */
.highlight .se {
color: #4070a0;
font-weight: bold
}
/* Literal.String.Escape */
.highlight .sh {
color: #4070a0
}
/* Literal.String.Heredoc */
.highlight .si {
color: #70a0d0;
font-style: italic
}
/* Literal.String.Interpol */
.highlight .sx {
color: #c65d09
}
/* Literal.String.Other */
.highlight .sr {
color: #235388
}
/* Literal.String.Regex */
.highlight .s1 {
color: #4070a0
}
/* Literal.String.Single */
.highlight .ss {
color: #517918
}
/* Literal.String.Symbol */
.highlight .bp {
color: #007020
}
/* Name.Builtin.Pseudo */
.highlight .fm {
color: #06287e
}
/* Name.Function.Magic */
.highlight .vc {
color: #bb60d5
}
/* Name.Variable.Class */
.highlight .vg {
color: #bb60d5
}
/* Name.Variable.Global */
.highlight .vi {
color: #bb60d5
}
/* Name.Variable.Instance */
.highlight .vm {
color: #bb60d5
}
/* Name.Variable.Magic */
.highlight .il {
color: #208050
}

Двоичные данные
third_party/python/psutil/docs/_static/logo.png поставляемый

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Просмотреть файл

@ -1,12 +0,0 @@
{#
basic/globaltoc.html
~~~~~~~~~~~~~~~~~~~~
Sphinx sidebar template: global table of contents.
:copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
<h3>{{ _('Manual') }}</h3>
{{ toctree() }}
<a href="{{ pathto(master_doc) }}">Back to Welcome</a>

Просмотреть файл

@ -1,4 +0,0 @@
{% extends "defindex.html" %}
{% block tables %}
{% endblock %}

Просмотреть файл

@ -1,8 +0,0 @@
<h3>Useful links</h3>
<ul>
<li><a href="https://github.com/giampaolo/psutil">Github project</a></li>
<li><a href="http://grodola.blogspot.com/search/label/psutil">Blog</a></li>
<li><a href="https://pypi.python.org/pypi?:action=display&name=psutil#downloads">Download</a></li>
<li><a href="https://github.com/giampaolo/psutil/issues">Issues</a></li>
<li><a href="http://groups.google.com/group/psutil/topics">Forum</a></li>
</ul>

Просмотреть файл

@ -1,66 +0,0 @@
{% extends "!page.html" %}
{% block extrahead %}
{{ super() }}
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
<script type="text/javascript">
// Store editor pop-up help state in localStorage
// so it does not re-pop-up itself between page loads.
// Do not even to pretend to support IE gracefully.
(function($) {
$(document).ready(function() {
var box = $("#editor-trap");
var klass = "toggled";
var storageKey = "toggled";
function toggle() {
box.toggleClass(klass);
// Store the toggle status in local storage as "has value string" or null
window.localStorage.setItem(storageKey, box.hasClass(klass) ? "toggled" : "not-toggled");
}
box.click(toggle);
// Check the persistent state of the editor pop-up
// Note that localStorage does not necessarily support boolean values (ugh!)
// http://stackoverflow.com/questions/3263161/cannot-set-boolean-values-in-localstorage
var v = window.localStorage.getItem(storageKey);
if(v == "toggled" || !v) {
box.addClass(klass);
}
});
})(jQuery);
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2097050-4']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
{% endblock %}
{% block rootrellink %}
<li><a href="https://github.com/giampaolo/psutil/"><img src="{{ pathto('_static/logo.png', 1) }}" style="height: 30px; vertical-align: middle; padding-right: 1em;" /> Project Homepage</a>{{ reldelim1 }}</li>
<li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
{% endblock %}
{% block footer %}
<div class="footer">
&copy; Copyright {{ copyright|e }}.
<br />
Last updated on {{ last_updated|e }}.
<br />
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version|e }}.
</div>
{% endblock %}

Просмотреть файл

@ -1,187 +0,0 @@
@import url("default.css");
body {
background-color: white;
margin-left: 1em;
margin-right: 1em;
}
div.related {
margin-bottom: 1.2em;
padding: 0.5em 0;
border-top: 1px solid #ccc;
margin-top: 0.5em;
}
div.related a:hover {
color: #0095C4;
}
div.related:first-child {
border-top: 0;
padding-top: 0;
border-bottom: 1px solid #ccc;
}
div.sphinxsidebar {
background-color: #eeeeee;
border-radius: 5px;
line-height: 130%;
font-size: smaller;
}
div.sphinxsidebar h3, div.sphinxsidebar h4 {
margin-top: 1.5em;
}
div.sphinxsidebarwrapper > h3:first-child {
margin-top: 0.2em;
}
div.sphinxsidebarwrapper > ul > li > ul > li {
margin-bottom: 0.4em;
}
div.sphinxsidebar a:hover {
color: #0095C4;
}
div.sphinxsidebar input {
font-family: 'Lucida Grande','Lucida Sans','DejaVu Sans',Arial,sans-serif;
border: 1px solid #999999;
font-size: smaller;
border-radius: 3px;
}
div.sphinxsidebar input[type=text] {
max-width: 150px;
}
div.body {
padding: 0 0 0 1.2em;
}
div.body p {
line-height: 140%;
}
div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 {
margin: 0;
border: 0;
padding: 0.3em 0;
}
div.body hr {
border: 0;
background-color: #ccc;
height: 1px;
}
div.body pre {
border-radius: 3px;
border: 1px solid #ac9;
}
div.body div.admonition, div.body div.impl-detail {
border-radius: 3px;
}
div.body div.impl-detail > p {
margin: 0;
}
div.body div.seealso {
border: 1px solid #dddd66;
}
div.body a {
color: #00608f;
}
div.body a:visited {
color: #30306f;
}
div.body a:hover {
color: #00B0E4;
}
tt, pre {
font-family: monospace, sans-serif;
font-size: 96.5%;
}
div.body tt {
border-radius: 3px;
}
div.body tt.descname {
font-size: 120%;
}
div.body tt.xref, div.body a tt {
font-weight: normal;
}
p.deprecated {
border-radius: 3px;
}
table.docutils {
border: 1px solid #ddd;
min-width: 20%;
border-radius: 3px;
margin-top: 10px;
margin-bottom: 10px;
}
table.docutils td, table.docutils th {
border: 1px solid #ddd !important;
border-radius: 3px;
}
table p, table li {
text-align: left !important;
}
table.docutils th {
background-color: #eee;
padding: 0.3em 0.5em;
}
table.docutils td {
background-color: white;
padding: 0.3em 0.5em;
}
table.footnote, table.footnote td {
border: 0 !important;
}
div.footer {
line-height: 150%;
margin-top: -2em;
text-align: right;
width: auto;
margin-right: 10px;
}
div.footer a:hover {
color: #0095C4;
}
div.body h1,
div.body h2,
div.body h3 {
background-color: #EAEAEA;
border-bottom: 1px solid #CCC;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 5px;
margin-top: 5px;
margin-bottom: 5px;
}
div.body h2 {
padding-left:10px;
}

Просмотреть файл

@ -1,23 +0,0 @@
[theme]
inherit = default
stylesheet = pydoctheme.css
pygments_style = sphinx
[options]
bodyfont = 'Lucida Grande', 'Lucida Sans', 'DejaVu Sans', Arial, sans-serif
headfont = 'Lucida Grande', 'Lucida Sans', 'DejaVu Sans', Arial, sans-serif
footerbgcolor = white
footertextcolor = #555555
relbarbgcolor = white
relbartextcolor = #666666
relbarlinkcolor = #444444
sidebarbgcolor = white
sidebartextcolor = #444444
sidebarlinkcolor = #444444
bgcolor = white
textcolor = #222222
linkcolor = #0090c0
visitedlinkcolor = #00608f
headtextcolor = #1a1a1a
headbgcolor = white
headlinkcolor = #aaaaaa

238
third_party/python/psutil/docs/conf.py поставляемый
Просмотреть файл

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# psutil documentation build configuration file, created by # psutil documentation build configuration file, created by
# sphinx-quickstart. # sphinx-quickstart on Wed Oct 19 21:54:30 2016.
# #
# This file is execfile()d with the current directory set to its # This file is execfile()d with the current directory set to its
# containing dir. # containing dir.
@ -12,12 +12,22 @@
# All configuration values have a default; values that are commented out # All configuration values have a default; values that are commented out
# serve to show the default. # serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
import datetime import datetime
import os import os
PROJECT_NAME = "psutil" PROJECT_NAME = "psutil"
AUTHOR = "Giampaolo Rodola'" AUTHOR = u"Giampaolo Rodola"
THIS_YEAR = str(datetime.datetime.now().year) THIS_YEAR = str(datetime.datetime.now().year)
HERE = os.path.abspath(os.path.dirname(__file__)) HERE = os.path.abspath(os.path.dirname(__file__))
@ -35,27 +45,33 @@ def get_version():
else: else:
raise ValueError("couldn't find version string") raise ValueError("couldn't find version string")
VERSION = get_version() VERSION = get_version()
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.0' #
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = ['sphinx.ext.autodoc', extensions = ['sphinx.ext.autodoc',
'sphinx.ext.coverage', 'sphinx.ext.coverage',
'sphinx.ext.pngmath', 'sphinx.ext.imgmath',
'sphinx.ext.viewcode', 'sphinx.ext.viewcode',
'sphinx.ext.intersphinx'] 'sphinx.ext.intersphinx']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_template'] templates_path = ['_templates']
# The suffix of source filenames. # The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst' source_suffix = '.rst'
# The encoding of source files. # The encoding of source files.
#
# source_encoding = 'utf-8-sig' # source_encoding = 'utf-8-sig'
# The master toctree document. # The master toctree document.
@ -64,6 +80,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = PROJECT_NAME project = PROJECT_NAME
copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR) copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR)
author = AUTHOR
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@ -71,35 +88,47 @@ copyright = '2009-%s, %s' % (THIS_YEAR, AUTHOR)
# #
# The short X.Y version. # The short X.Y version.
version = VERSION version = VERSION
# The full version, including alpha/beta/rc tags.
release = VERSION
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
# language = None #
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some # There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used: # non-false value, then it is used:
#
# today = '' # today = ''
#
# Else, today_fmt is used as the format for a strftime call. # Else, today_fmt is used as the format for a strftime call.
#
# today_fmt = '%B %d, %Y' # today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
exclude_patterns = ['_build'] # This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The reST default role (used for this markup: `text`) to use for all # The reST default role (used for this markup: `text`) to use for all
# documents. # documents.
#
# default_role = None # default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text. # If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True #
# add_function_parentheses = True
# If true, the current module name will be prepended to all description # If true, the current module name will be prepended to all description
# unit titles (such as .. function::). # unit titles (such as .. function::).
#
# add_module_names = True # add_module_names = True
autodoc_docstring_signature = True
# If true, sectionauthor and moduleauthor directives will be shown in the # If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default. # output. They are ignored by default.
#
# show_authors = False # show_authors = False
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
@ -108,141 +137,240 @@ pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting. # A list of ignored prefixes for module index sorting.
# modindex_common_prefix = [] # modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
# -- Options for HTML output ------------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
html_theme = 'pydoctheme' #
html_theme_options = {'collapsiblesidebar': True} # html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ["_themes"] # html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to # The name for this set of Sphinx documents.
# "<project> v<release> documentation". # "<project> v<release> documentation" by default.
html_title = "{project} {version} documentation".format(**locals()) #
# html_title = u'psutil v1.0'
# A shorter title for the navigation bar. Default is the same as html_title. # A shorter title for the navigation bar. Default is the same as html_title.
#
# html_short_title = None # html_short_title = None
# The name of an image file (relative to this directory) to place at the top # The name of an image file (relative to this directory) to place at the top
# of the sidebar. # of the sidebar.
# html_logo = 'logo.png' #
# html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or
# 32x32 pixels large.
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = '_static/favicon.ico'
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static'] html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # Add any extra paths that contain custom files (such as robots.txt or
# using the given strftime format. # .htaccess) here, relative to this directory. These files are copied
html_last_updated_fmt = '%b %d, %Y' # directly to the root of the documentation.
#
# html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#
# html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to # If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities. # typographically correct entities.
html_use_smartypants = True #
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
html_sidebars = { #
'index': 'indexsidebar.html', # html_sidebars = {}
'**': ['globaltoc.html',
'relations.html',
'sourcelink.html',
'searchbox.html']
}
# Additional templates that should be rendered to pages, maps page names to # Additional templates that should be rendered to pages, maps page names to
# template names. # template names.
# html_additional_pages = { #
# 'index': 'indexcontent.html', # html_additional_pages = {}
# }
# If false, no module index is generated. # If false, no module index is generated.
html_domain_indices = False #
# html_domain_indices = True
# If false, no index is generated. # If false, no index is generated.
html_use_index = True #
# html_use_index = True
# If true, the index is split into individual pages for each letter. # If true, the index is split into individual pages for each letter.
#
# html_split_index = False # html_split_index = False
# If true, links to the reST sources are added to the pages. # If true, links to the reST sources are added to the pages.
#
# html_show_sourcelink = True # html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
# html_show_sphinx = True # html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True # html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will # If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the # contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served. # base URL from which the finished HTML is served.
#
# html_use_opensearch = '' # html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml"). # This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None # html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
#
# html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = '%s-doc' % PROJECT_NAME htmlhelp_basename = '%s-doc' % PROJECT_NAME
# -- Options for LaTeX output ------------------------------------------------ # -- Options for LaTeX output ---------------------------------------------
# The paper size ('letter' or 'a4'). latex_elements = {
# latex_paper_size = 'letter' # The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt'). # The font size ('10pt', '11pt' or '12pt').
# latex_font_size = '10pt' #
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass # (source start file, target name, title,
# [howto/manual]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
('index', '%s.tex' % PROJECT_NAME, (master_doc, 'psutil.tex', u'psutil Documentation',
'%s documentation' % PROJECT_NAME, AUTHOR), AUTHOR, 'manual'),
] ]
# The name of an image file (relative to this directory) to place at # The name of an image file (relative to this directory) to place at the top of
# the top of the title page. # the title page.
#
# latex_logo = None # latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts, # For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters. # not chapters.
#
# latex_use_parts = False # latex_use_parts = False
# If true, show page references after internal links. # If true, show page references after internal links.
#
# latex_show_pagerefs = False # latex_show_pagerefs = False
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
#
# latex_show_urls = False # latex_show_urls = False
# Additional stuff for the LaTeX preamble.
# latex_preamble = ''
# Documents to append as an appendix to all manuals. # Documents to append as an appendix to all manuals.
#
# latex_appendices = [] # latex_appendices = []
# It false, will not define \strong, \code, itleref, \crossref ... but only
# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
# packages.
#
# latex_keep_old_macro_names = True
# If false, no module index is generated. # If false, no module index is generated.
#
# latex_domain_indices = True # latex_domain_indices = True
# -- Options for manual page output ------------------------------------------ # -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
('index', PROJECT_NAME, '%s documentation' % PROJECT_NAME, [AUTHOR], 1) (master_doc, 'psutil', u'psutil Documentation',
[author], 1)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
#
# man_show_urls = False # man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'psutil', u'psutil Documentation',
author, 'psutil', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#
# texinfo_appendices = []
# If false, no module index is generated.
#
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False
html_context = {
'css_files': [
'https://media.readthedocs.org/css/sphinx_rtd_theme.css',
'https://media.readthedocs.org/css/readthedocs-doc-embed.css',
'_static/css/custom.css',
],
}

2770
third_party/python/psutil/docs/index.rst поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

484
third_party/python/psutil/docs/make.bat поставляемый
Просмотреть файл

@ -1,242 +1,242 @@
@ECHO OFF @ECHO OFF
REM Command file for Sphinx documentation REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" ( if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build set SPHINXBUILD=sphinx-build
) )
set BUILDDIR=_build set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" ( if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
) )
if "%1" == "" goto help if "%1" == "" goto help
if "%1" == "help" ( if "%1" == "help" (
:help :help
echo.Please use `make ^<target^>` where ^<target^> is one of echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files echo. pickle to make pickle files
echo. json to make JSON files echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files echo. text to make text files
echo. man to make manual pages echo. man to make manual pages
echo. texinfo to make Texinfo files echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled echo. doctest to run all doctests embedded in the documentation if enabled
goto end goto end
) )
if "%1" == "clean" ( if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\* del /q /s %BUILDDIR%\*
goto end goto end
) )
%SPHINXBUILD% 2> nul %SPHINXBUILD% 2> nul
if errorlevel 9009 ( if errorlevel 9009 (
echo. echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH. echo.may add the Sphinx directory to PATH.
echo. echo.
echo.If you don't have Sphinx installed, grab it from echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/ echo.http://sphinx-doc.org/
exit /b 1 exit /b 1
) )
if "%1" == "html" ( if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html. echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end goto end
) )
if "%1" == "dirhtml" ( if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end goto end
) )
if "%1" == "singlehtml" ( if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end goto end
) )
if "%1" == "pickle" ( if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished; now you can process the pickle files. echo.Build finished; now you can process the pickle files.
goto end goto end
) )
if "%1" == "json" ( if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished; now you can process the JSON files. echo.Build finished; now you can process the JSON files.
goto end goto end
) )
if "%1" == "htmlhelp" ( if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished; now you can run HTML Help Workshop with the ^ echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp. .hhp project file in %BUILDDIR%/htmlhelp.
goto end goto end
) )
if "%1" == "qthelp" ( if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^ echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this: .qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\psutil.qhcp echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyftpdlib.qhcp
echo.To view the help file: echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\psutil.ghc echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyftpdlib.ghc
goto end goto end
) )
if "%1" == "devhelp" ( if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. echo.Build finished.
goto end goto end
) )
if "%1" == "epub" ( if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub. echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end goto end
) )
if "%1" == "latex" ( if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end goto end
) )
if "%1" == "latexpdf" ( if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex cd %BUILDDIR%/latex
make all-pdf make all-pdf
cd %BUILDDIR%/.. cd %BUILDDIR%/..
echo. echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex. echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end goto end
) )
if "%1" == "latexpdfja" ( if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex cd %BUILDDIR%/latex
make all-pdf-ja make all-pdf-ja
cd %BUILDDIR%/.. cd %BUILDDIR%/..
echo. echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex. echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end goto end
) )
if "%1" == "text" ( if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The text files are in %BUILDDIR%/text. echo.Build finished. The text files are in %BUILDDIR%/text.
goto end goto end
) )
if "%1" == "man" ( if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man. echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end goto end
) )
if "%1" == "texinfo" ( if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end goto end
) )
if "%1" == "gettext" ( if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale. echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end goto end
) )
if "%1" == "changes" ( if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.The overview file is in %BUILDDIR%/changes. echo.The overview file is in %BUILDDIR%/changes.
goto end goto end
) )
if "%1" == "linkcheck" ( if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Link check complete; look for any errors in the above output ^ echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt. or in %BUILDDIR%/linkcheck/output.txt.
goto end goto end
) )
if "%1" == "doctest" ( if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Testing of doctests in the sources finished, look at the ^ echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt. results in %BUILDDIR%/doctest/output.txt.
goto end goto end
) )
if "%1" == "xml" ( if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml. echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end goto end
) )
if "%1" == "pseudoxml" ( if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1 if errorlevel 1 exit /b 1
echo. echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end goto end
) )
:end :end

11
third_party/python/psutil/docs/xxx поставляемый
Просмотреть файл

@ -1,11 +0,0 @@
cpu 1974613 1749 485728 6305758 80280 15 5924 0 0 0
cpu0 519156 374 132999 5977865 72925 10 1458 0 0 0
cpu1 524667 401 125931 108960 2110 4 2214 0 0 0
cpu2 462286 520 117046 109514 2666 0 828 0 0 0
cpu3 468502 453 109750 109418 2578 0 1424 0 0 0

Просмотреть файл

@ -1,78 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
A clone of 'ifconfig' on UNIX.
$ python examples/ifconfig.py
lo (speed=0MB, duplex=?, mtu=65536, up=yes):
IPv4 address : 127.0.0.1
broadcast : 127.0.0.1
netmask : 255.0.0.0
IPv6 address : ::1
netmask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
MAC address : 00:00:00:00:00:00
broadcast : 00:00:00:00:00:00
wlan0 (speed=0MB, duplex=?, mtu=1500, up=yes):
IPv4 address : 10.0.3.1
broadcast : 10.0.3.255
netmask : 255.255.255.0
IPv6 address : fe80::3005:adff:fe31:8698
netmask : ffff:ffff:ffff:ffff::
MAC address : 32:05:ad:31:86:98
broadcast : ff:ff:ff:ff:ff:ff
eth0 (speed=100MB, duplex=full, mtu=1500, up=yes):
IPv4 address : 192.168.1.2
broadcast : 192.168.1.255
netmask : 255.255.255.0
IPv6 address : fe80::c685:8ff:fe45:641
netmask : ffff:ffff:ffff:ffff::
MAC address : c4:85:08:45:06:41
broadcast : ff:ff:ff:ff:ff:ff
"""
from __future__ import print_function
import socket
import psutil
af_map = {
socket.AF_INET: 'IPv4',
socket.AF_INET6: 'IPv6',
psutil.AF_LINK: 'MAC',
}
duplex_map = {
psutil.NIC_DUPLEX_FULL: "full",
psutil.NIC_DUPLEX_HALF: "half",
psutil.NIC_DUPLEX_UNKNOWN: "?",
}
def main():
stats = psutil.net_if_stats()
for nic, addrs in psutil.net_if_addrs().items():
if nic in stats:
print("%s (speed=%sMB, duplex=%s, mtu=%s, up=%s):" % (
nic, stats[nic].speed, duplex_map[stats[nic].duplex],
stats[nic].mtu, "yes" if stats[nic].isup else "no"))
else:
print("%s:" % (nic))
for addr in addrs:
print(" %-8s" % af_map.get(addr.family, addr.family), end="")
print(" address : %s" % addr.address)
if addr.broadcast:
print(" broadcast : %s" % addr.broadcast)
if addr.netmask:
print(" netmask : %s" % addr.netmask)
print("")
if __name__ == '__main__':
main()

Просмотреть файл

@ -1,167 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Print detailed information about a process.
Author: Giampaolo Rodola' <g.rodola@gmail.com>
$ python examples/process_detail.py
pid 820
name python
exe /usr/bin/python2.7
parent 29613 (bash)
cmdline python examples/process_detail.py
started 2014-41-27 03:41
user giampaolo
uids real=1000, effective=1000, saved=1000
gids real=1000, effective=1000, saved=1000
terminal /dev/pts/17
cwd /ssd/svn/psutil
memory 0.1% (resident=10.6M, virtual=58.5M)
cpu 0.0% (user=0.09, system=0.0)
status running
niceness 0
num threads 1
I/O bytes-read=0B, bytes-written=0B
open files
running threads id=820, user-time=0.09, sys-time=0.0
"""
import datetime
import os
import socket
import sys
import psutil
POSIX = os.name == 'posix'
def convert_bytes(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sB" % n
def print_(a, b):
if sys.stdout.isatty() and POSIX:
fmt = '\x1b[1;32m%-17s\x1b[0m %s' % (a, b)
else:
fmt = '%-15s %s' % (a, b)
# python 2/3 compatibility layer
sys.stdout.write(fmt + '\n')
sys.stdout.flush()
def run(pid):
ACCESS_DENIED = ''
try:
p = psutil.Process(pid)
pinfo = p.as_dict(ad_value=ACCESS_DENIED)
except psutil.NoSuchProcess as err:
sys.exit(str(err))
try:
parent = p.parent()
if parent:
parent = '(%s)' % parent.name()
else:
parent = ''
except psutil.Error:
parent = ''
if pinfo['create_time'] != ACCESS_DENIED:
started = datetime.datetime.fromtimestamp(
pinfo['create_time']).strftime('%Y-%m-%d %H:%M')
else:
started = ACCESS_DENIED
io = pinfo.get('io_counters', ACCESS_DENIED)
if pinfo['memory_info'] != ACCESS_DENIED:
mem = '%s%% (resident=%s, virtual=%s) ' % (
round(pinfo['memory_percent'], 1),
convert_bytes(pinfo['memory_info'].rss),
convert_bytes(pinfo['memory_info'].vms))
else:
mem = ACCESS_DENIED
children = p.children()
print_('pid', pinfo['pid'])
print_('name', pinfo['name'])
print_('exe', pinfo['exe'])
print_('parent', '%s %s' % (pinfo['ppid'], parent))
print_('cmdline', ' '.join(pinfo['cmdline']))
print_('started', started)
print_('user', pinfo['username'])
if POSIX and pinfo['uids'] and pinfo['gids']:
print_('uids', 'real=%s, effective=%s, saved=%s' % pinfo['uids'])
if POSIX and pinfo['gids']:
print_('gids', 'real=%s, effective=%s, saved=%s' % pinfo['gids'])
if POSIX:
print_('terminal', pinfo['terminal'] or '')
print_('cwd', pinfo['cwd'])
print_('memory', mem)
print_('cpu', '%s%% (user=%s, system=%s)' % (
pinfo['cpu_percent'],
getattr(pinfo['cpu_times'], 'user', '?'),
getattr(pinfo['cpu_times'], 'system', '?')))
print_('status', pinfo['status'])
print_('niceness', pinfo['nice'])
print_('num threads', pinfo['num_threads'])
if io != ACCESS_DENIED:
print_('I/O', 'bytes-read=%s, bytes-written=%s' % (
convert_bytes(io.read_bytes),
convert_bytes(io.write_bytes)))
if children:
print_('children', '')
for child in children:
print_('', 'pid=%s name=%s' % (child.pid, child.name()))
if pinfo['open_files'] != ACCESS_DENIED:
print_('open files', '')
for file in pinfo['open_files']:
print_('', 'fd=%s %s ' % (file.fd, file.path))
if pinfo['threads']:
print_('running threads', '')
for thread in pinfo['threads']:
print_('', 'id=%s, user-time=%s, sys-time=%s' % (
thread.id, thread.user_time, thread.system_time))
if pinfo['connections'] not in (ACCESS_DENIED, []):
print_('open connections', '')
for conn in pinfo['connections']:
if conn.type == socket.SOCK_STREAM:
type = 'TCP'
elif conn.type == socket.SOCK_DGRAM:
type = 'UDP'
else:
type = 'UNIX'
lip, lport = conn.laddr
if not conn.raddr:
rip, rport = '*', '*'
else:
rip, rport = conn.raddr
print_('', '%s:%s -> %s:%s type=%s status=%s' % (
lip, lport, rip, rport, type, conn.status))
def main(argv=None):
if argv is None:
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())

173
third_party/python/psutil/make.bat поставляемый
Просмотреть файл

@ -23,179 +23,10 @@ if "%PYTHON%" == "" (
set PYTHON=C:\Python27\python.exe set PYTHON=C:\Python27\python.exe
) )
if "%TSCRIPT%" == "" ( if "%TSCRIPT%" == "" (
set TSCRIPT=test\test_psutil.py set TSCRIPT=psutil\tests\__main__.py
) )
set PYTHON26=C:\Python26\python.exe
set PYTHON27=C:\Python27\python.exe
set PYTHON33=C:\Python33\python.exe
set PYTHON34=C:\Python34\python.exe
set PYTHON26-64=C:\Python26-64\python.exe
set PYTHON27-64=C:\Python27-64\python.exe
set PYTHON33-64=C:\Python33-64\python.exe
set PYTHON34-64=C:\Python34-64\python.exe
set ALL_PYTHONS=%PYTHON26% %PYTHON27% %PYTHON33% %PYTHON34% %PYTHON26-64% %PYTHON27-64% %PYTHON33-64% %PYTHON34-64%
rem Needed to locate the .pypirc file and upload exes on PYPI. rem Needed to locate the .pypirc file and upload exes on PYPI.
set HOME=%USERPROFILE% set HOME=%USERPROFILE%
rem ========================================================================== %PYTHON% scripts\internal\winmake.py %1 %2 %3 %4 %5 %6
if "%1" == "help" (
:help
echo Run `make ^<target^>` where ^<target^> is one of:
echo build compile without installing
echo build-all build exes + wheels
echo clean clean build files
echo flake8 run flake8
echo install compile and install
echo setup-dev-env install pip, pywin32, wheels, etc. for all python versions
echo test run tests
echo test-memleaks run memory leak tests
echo test-process run process related tests
echo test-system run system APIs related tests
echo uninstall uninstall
echo upload-all upload exes + wheels
goto :eof
)
if "%1" == "clean" (
for /r %%R in (__pycache__) do if exist %%R (rmdir /S /Q %%R)
for /r %%R in (*.pyc) do if exist %%R (del /s %%R)
for /r %%R in (*.pyd) do if exist %%R (del /s %%R)
for /r %%R in (*.orig) do if exist %%R (del /s %%R)
for /r %%R in (*.bak) do if exist %%R (del /s %%R)
for /r %%R in (*.rej) do if exist %%R (del /s %%R)
if exist psutil.egg-info (rmdir /S /Q psutil.egg-info)
if exist build (rmdir /S /Q build)
if exist dist (rmdir /S /Q dist)
goto :eof
)
if "%1" == "build" (
:build
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
%PYTHON% setup.py build
if %errorlevel% neq 0 goto :error
rem copies *.pyd files in ./psutil directory in order to allow
rem "import psutil" when using the interactive interpreter from
rem within this directory.
%PYTHON% setup.py build_ext -i
if %errorlevel% neq 0 goto :error
goto :eof
)
if "%1" == "install" (
:install
call :build
%PYTHON% setup.py install
goto :eof
)
if "%1" == "uninstall" (
for %%A in ("%PYTHON%") do (
set folder=%%~dpA
)
for /F "delims=" %%i in ('dir /b %folder%\Lib\site-packages\*psutil*') do (
rmdir /S /Q %folder%\Lib\site-packages\%%i
)
goto :eof
)
if "%1" == "test" (
call :install
%PYTHON% %TSCRIPT%
goto :eof
)
if "%1" == "test-process" (
call :install
%PYTHON% -m unittest -v test.test_psutil.TestProcess
goto :eof
)
if "%1" == "test-system" (
call :install
%PYTHON% -m unittest -v test.test_psutil.TestSystem
goto :eof
)
if "%1" == "test-memleaks" (
call :install
%PYTHON% test\test_memory_leaks.py
goto :eof
)
if "%1" == "build-all" (
:build-all
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
for %%P in (%ALL_PYTHONS%) do (
@echo ------------------------------------------------
@echo building exe for %%P
@echo ------------------------------------------------
%%P setup.py build bdist_wininst || goto :error
@echo ------------------------------------------------
@echo building wheel for %%P
@echo ------------------------------------------------
%%P setup.py build bdist_wheel || goto :error
)
echo OK
goto :eof
)
if "%1" == "upload-all" (
:upload-exes
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat"
for %%P in (%ALL_PYTHONS%) do (
@echo ------------------------------------------------
@echo uploading exe for %%P
@echo ------------------------------------------------
%%P setup.py build bdist_wininst upload || goto :error
@echo ------------------------------------------------
@echo uploading wheel for %%P
@echo ------------------------------------------------
%%P setup.py build bdist_wheel upload || goto :error
)
echo OK
goto :eof
)
if "%1" == "setup-dev-env" (
:setup-env
@echo ------------------------------------------------
@echo downloading pip installer
@echo ------------------------------------------------
C:\python27\python.exe -c "import urllib2; r = urllib2.urlopen('https://raw.github.com/pypa/pip/master/contrib/get-pip.py'); open('get-pip.py', 'wb').write(r.read())"
for %%P in (%ALL_PYTHONS%) do (
@echo ------------------------------------------------
@echo installing pip for %%P
@echo ------------------------------------------------
%%P get-pip.py
)
for %%P in (%ALL_PYTHONS%) do (
@echo ------------------------------------------------
@echo installing deps for %%P
@echo ------------------------------------------------
rem mandatory / for unittests
%%P -m pip install unittest2 ipaddress mock wmi wheel pypiwin32 --upgrade
rem nice to have
%%P -m pip install ipdb pep8 pyflakes flake8 --upgrade
)
goto :eof
)
if "%1" == "flake8" (
:flake8
%PYTHON% -c "from flake8.main import main; main()"
goto :eof
)
goto :help
:error
@echo ------------------------------------------------
@echo last command exited with error code %errorlevel%
@echo ------------------------------------------------
@exit /b %errorlevel%
goto :eof

Просмотреть файл

@ -1,434 +0,0 @@
Metadata-Version: 1.1
Name: psutil
Version: 3.1.1
Summary: psutil is a cross-platform library for retrieving information onrunning processes and system utilization (CPU, memory, disks, network)in Python.
Home-page: https://github.com/giampaolo/psutil
Author: Giampaolo Rodola
Author-email: g.rodola <at> gmail <dot> com
License: BSD
Description: .. image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pypi.python.org/pypi/psutil#downloads
:alt: Downloads this month
.. image:: https://api.travis-ci.org/giampaolo/psutil.png?branch=master
:target: https://travis-ci.org/giampaolo/psutil
:alt: Linux tests (Travis)
.. image:: https://ci.appveyor.com/api/projects/status/qdwvw7v1t915ywr5/branch/master?svg=true
:target: https://ci.appveyor.com/project/giampaolo/psutil
:alt: Windows tests (Appveyor)
.. image:: https://coveralls.io/repos/giampaolo/psutil/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
.. image:: https://img.shields.io/pypi/v/psutil.svg
:target: https://pypi.python.org/pypi/psutil/
:alt: Latest version
.. image:: https://img.shields.io/github/stars/giampaolo/psutil.svg
:target: https://github.com/giampaolo/psutil/
:alt: Github stars
.. image:: https://img.shields.io/scrutinizer/g/giampaolo/psutil.svg
:target: https://scrutinizer-ci.com/g/giampaolo/psutil/
:alt: Code quality (scrutinizer-ci.com)
.. image:: https://img.shields.io/pypi/l/psutil.svg
:target: https://pypi.python.org/pypi/psutil/
:alt: License
===========
Quick links
===========
- `Home page <https://github.com/giampaolo/psutil>`_
- `Documentation <http://pythonhosted.org/psutil/>`_
- `Installation <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
- `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_
- `Forum <http://groups.google.com/group/psutil/topics>`_
- `Blog <http://grodola.blogspot.com/search/label/psutil>`_
- `Development guide <https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst>`_
- `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`_
=======
Summary
=======
psutil (python system and process utilities) is a cross-platform library for
retrieving information on **running processes** and **system utilization**
(CPU, memory, disks, network) in Python. It is useful mainly for **system
monitoring**, **profiling and limiting process resources** and **management of
running processes**. It implements many functionalities offered by command line
tools such as: ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice,
ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap. It currently supports
**Linux, Windows, OSX, FreeBSD** and **Sun Solaris**, both **32-bit** and
**64-bit** architectures, with Python versions from **2.6 to 3.5** (users of
Python 2.4 and 2.5 may use `2.1.3 <https://pypi.python.org/pypi?name=psutil&version=2.1.3&:action=files>`__ version).
`PyPy <http://pypy.org/>`__ is also known to work.
====================
Example applications
====================
.. image:: http://psutil.googlecode.com/svn/wiki/images/top-thumb.png
:target: http://psutil.googlecode.com/svn/wiki/images/top.png
:alt: top
.. image:: http://psutil.googlecode.com/svn/wiki/images/nettop-thumb.png
:target: http://psutil.googlecode.com/svn/wiki/images/nettop.png
:alt: nettop
.. image:: http://psutil.googlecode.com/svn/wiki/images/iotop-thumb.png
:target: http://psutil.googlecode.com/svn/wiki/images/iotop.png
:alt: iotop
See also:
* https://github.com/nicolargo/glances
* https://github.com/google/grr
* https://github.com/Jahaja/psdash
==============
Example usages
==============
CPU
===
.. code-block:: python
>>> import psutil
>>> psutil.cpu_times()
scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1)
...
4.0
5.9
3.8
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1, percpu=True)
...
[4.0, 6.9, 3.7, 9.2]
[7.0, 8.5, 2.4, 2.1]
[1.2, 9.0, 9.9, 7.2]
>>>
>>>
>>> for x in range(3):
... psutil.cpu_times_percent(interval=1, percpu=False)
...
scputimes(user=1.5, nice=0.0, system=0.5, idle=96.5, iowait=1.5, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=1.0, nice=0.0, system=0.0, idle=99.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=2.0, nice=0.0, system=0.0, idle=98.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
>>>
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
>>>
Memory
======
.. code-block:: python
>>> psutil.virtual_memory()
svmem(total=8374149120, available=2081050624, percent=75.1, used=8074080256, free=300068864, active=3294920704, inactive=1361616896, buffers=529895424, cached=1251086336)
>>> psutil.swap_memory()
sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
>>>
Disks
=====
.. code-block:: python
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
>>>
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>>
>>> psutil.disk_io_counters(perdisk=False)
sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568)
>>>
Network
=======
.. code-block:: python
>>> psutil.net_io_counters(pernic=True)
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>>
>>> psutil.net_connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED', pid=1254),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING', pid=2987),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED', pid=None),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT', pid=None)
...]
>>>
>>> psutil.net_if_addrs()
{'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1'),
snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00')],
'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255'),
snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None),
snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff')]}
>>>
>>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
Other system info
=================
.. code-block:: python
>>> psutil.users()
[user(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0),
user(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0)]
>>>
>>> psutil.boot_time()
1365519115.0
>>>
Process management
==================
.. code-block:: python
>>> import psutil
>>> psutil.pids()
[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224,
268, 1215, 1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355,
2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245,
4263, 4282, 4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358,
4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446, 5167, 5234, 5235,
5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
>>>
>>> p = psutil.Process(7055)
>>> p.name()
'python'
>>> p.exe()
'/usr/bin/python'
>>> p.cwd()
'/home/giampaolo'
>>> p.cmdline()
['/usr/bin/python', 'main.py']
>>>
>>> p.status()
'running'
>>> p.username()
'giampaolo'
>>> p.create_time()
1267551141.5019531
>>> p.terminal()
'/dev/pts/0'
>>>
>>> p.uids()
puids(real=1000, effective=1000, saved=1000)
>>> p.gids()
pgids(real=1000, effective=1000, saved=1000)
>>>
>>> p.cpu_times()
pcputimes(user=1.02, system=0.31)
>>> p.cpu_percent(interval=1.0)
12.1
>>> p.cpu_affinity()
[0, 1, 2, 3]
>>> p.cpu_affinity([0]) # set
>>>
>>> p.memory_percent()
0.63423
>>>
>>> p.memory_info()
pmem(rss=7471104, vms=68513792)
>>> p.memory_info_ex()
extmem(rss=9662464, vms=49192960, shared=3612672, text=2564096, lib=0, data=5754880, dirty=0)
>>> p.memory_maps()
[pmmap_grouped(path='/lib/x86_64-linux-gnu/libutil-2.15.so', rss=16384, anonymous=8192, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libc-2.15.so', rss=6384, anonymous=15, swap=0),
pmmap_grouped(path='/lib/x86_64-linux-gnu/libcrypto.so.1.0.0', rss=34124, anonymous=1245, swap=0),
pmmap_grouped(path='[heap]', rss=54653, anonymous=8192, swap=0),
pmmap_grouped(path='[stack]', rss=1542, anonymous=166, swap=0),
...]
>>>
>>> p.io_counters()
pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632)
>>>
>>> p.open_files()
[popenfile(path='/home/giampaolo/svn/psutil/somefile', fd=3)]
>>>
>>> p.connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 48776), raddr=('93.186.135.91', 80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 43761), raddr=('72.14.234.100', 80), status='CLOSING'),
pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 60759), raddr=('72.14.234.104', 80), status='ESTABLISHED'),
pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=('10.0.0.1', 51314), raddr=('72.14.234.83', 443), status='SYN_SENT')]
>>>
>>> p.num_threads()
4
>>> p.num_fds()
8
>>> p.threads()
[pthread(id=5234, user_time=22.5, system_time=9.2891),
pthread(id=5235, user_time=0.0, system_time=0.0),
pthread(id=5236, user_time=0.0, system_time=0.0),
pthread(id=5237, user_time=0.0707, system_time=1.1)]
>>>
>>> p.num_ctx_switches()
pctxsw(voluntary=78, involuntary=19)
>>>
>>> p.nice()
0
>>> p.nice(10) # set
>>>
>>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # IO priority (Win and Linux only)
>>> p.ionice()
pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
>>>
>>> p.rlimit(psutil.RLIMIT_NOFILE, (5, 5)) # set resource limits (Linux only)
>>> p.rlimit(psutil.RLIMIT_NOFILE)
(5, 5)
>>>
>>> p.suspend()
>>> p.resume()
>>>
>>> p.terminate()
>>> p.wait(timeout=3)
0
>>>
>>> psutil.test()
USER PID %CPU %MEM VSZ RSS TTY START TIME COMMAND
root 1 0.0 0.0 24584 2240 Jun17 00:00 init
root 2 0.0 0.0 0 0 Jun17 00:00 kthreadd
root 3 0.0 0.0 0 0 Jun17 00:05 ksoftirqd/0
...
giampaolo 31475 0.0 0.0 20760 3024 /dev/pts/0 Jun19 00:00 python2.4
giampaolo 31721 0.0 2.2 773060 181896 00:04 10:30 chrome
root 31763 0.0 0.0 0 0 00:05 00:00 kworker/0:1
>>>
Further process APIs
====================
.. code-block:: python
>>> for p in psutil.process_iter():
... print(p)
...
psutil.Process(pid=1, name='init')
psutil.Process(pid=2, name='kthreadd')
psutil.Process(pid=3, name='ksoftirqd/0')
...
>>>
>>> def on_terminate(proc):
... print("process {} terminated".format(proc))
...
>>> # waits for multiple processes to terminate
>>> gone, alive = psutil.wait_procs(procs_list, 3, callback=on_terminate)
>>>
======
Donate
======
A lot of time and effort went into making psutil as it is right now.
If you feel psutil is useful to you or your business and want to support its future development please consider donating me (`Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`_) some money.
I only ask for a small donation, but of course I appreciate any amount.
.. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
:alt: Donate via PayPal
Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <http://www.linkedin.com/in/grodola>`_.
============
Mailing list
============
http://groups.google.com/group/psutil/
========
Timeline
========
- 2015-07-15: `psutil-3.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.1.tar.gz>`_
- 2015-07-15: `psutil-3.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.1.0.tar.gz>`_
- 2015-06-18: `psutil-3.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.1.tar.gz>`_
- 2015-06-13: `psutil-3.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-3.0.0.tar.gz>`_
- 2015-02-02: `psutil-2.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.1.tar.gz>`_
- 2015-01-06: `psutil-2.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.2.0.tar.gz>`_
- 2014-09-26: `psutil-2.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.3.tar.gz>`_
- 2014-09-21: `psutil-2.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.2.tar.gz>`_
- 2014-04-30: `psutil-2.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.1.tar.gz>`_
- 2014-04-08: `psutil-2.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.1.0.tar.gz>`_
- 2014-03-10: `psutil-2.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz>`_
- 2013-11-25: `psutil-1.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.1.tar.gz>`_
- 2013-11-20: `psutil-1.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.2.0.tar.gz>`_
- 2013-11-07: `psutil-1.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.3.tar.gz>`_
- 2013-10-22: `psutil-1.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.2.tar.gz>`_
- 2013-10-08: `psutil-1.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.1.tar.gz>`_
- 2013-09-28: `psutil-1.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.1.0.tar.gz>`_
- 2013-07-12: `psutil-1.0.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.1.tar.gz>`_
- 2013-07-10: `psutil-1.0.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-1.0.0.tar.gz>`_
- 2013-05-03: `psutil-0.7.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.1.tar.gz>`_
- 2013-04-12: `psutil-0.7.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.7.0.tar.gz>`_
- 2012-08-16: `psutil-0.6.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.1.tar.gz>`_
- 2012-08-13: `psutil-0.6.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.6.0.tar.gz>`_
- 2012-06-29: `psutil-0.5.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.1.tar.gz>`_
- 2012-06-27: `psutil-0.5.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.5.0.tar.gz>`_
- 2011-12-14: `psutil-0.4.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.1.tar.gz>`_
- 2011-10-29: `psutil-0.4.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.4.0.tar.gz>`_
- 2011-07-08: `psutil-0.3.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.3.0.tar.gz>`_
- 2011-03-20: `psutil-0.2.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.1.tar.gz>`_
- 2010-11-13: `psutil-0.2.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.2.0.tar.gz>`_
- 2010-03-02: `psutil-0.1.3.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.3.tar.gz>`_
- 2009-05-06: `psutil-0.1.2.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.2.tar.gz>`_
- 2009-03-06: `psutil-0.1.1.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.1.tar.gz>`_
- 2009-01-27: `psutil-0.1.0.tar.gz <https://pypi.python.org/packages/source/p/psutil/psutil-0.1.0.tar.gz>`_
Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,pstree,monitoring,ulimit,prlimit
Platform: Platform Independent
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Win32 (MS Windows)
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
Classifier: Operating System :: Microsoft
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: BSD :: FreeBSD
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: POSIX :: SunOS/Solaris
Classifier: Operating System :: POSIX
Classifier: Programming Language :: C
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Benchmark
Classifier: Topic :: System :: Hardware
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Networking :: Monitoring
Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities

Просмотреть файл

@ -1,96 +0,0 @@
.coveragerc
.git-pre-commit
.gitignore
.travis.yml
CREDITS
HISTORY.rst
INSTALL.rst
LICENSE
MANIFEST.in
Makefile
README.rst
TODO
make.bat
setup.py
tox.ini
docs/Makefile
docs/README
docs/conf.py
docs/index.rst
docs/make.bat
docs/xxx
docs/_static/copybutton.js
docs/_static/favicon.ico
docs/_static/logo.png
docs/_static/sidebar.js
docs/_template/globaltoc.html
docs/_template/indexcontent.html
docs/_template/indexsidebar.html
docs/_template/page.html
docs/_themes/pydoctheme/theme.conf
docs/_themes/pydoctheme/static/pydoctheme.css
examples/disk_usage.py
examples/free.py
examples/ifconfig.py
examples/iotop.py
examples/killall.py
examples/meminfo.py
examples/netstat.py
examples/nettop.py
examples/pidof.py
examples/pmap.py
examples/process_detail.py
examples/ps.py
examples/pstree.py
examples/top.py
examples/who.py
psutil/__init__.py
psutil/_common.py
psutil/_compat.py
psutil/_psbsd.py
psutil/_pslinux.py
psutil/_psosx.py
psutil/_psposix.py
psutil/_pssunos.py
psutil/_psutil_bsd.c
psutil/_psutil_bsd.h
psutil/_psutil_common.c
psutil/_psutil_common.h
psutil/_psutil_linux.c
psutil/_psutil_linux.h
psutil/_psutil_osx.c
psutil/_psutil_osx.h
psutil/_psutil_posix.c
psutil/_psutil_posix.h
psutil/_psutil_sunos.c
psutil/_psutil_sunos.h
psutil/_psutil_windows.c
psutil/_psutil_windows.h
psutil/_pswindows.py
psutil.egg-info/PKG-INFO
psutil.egg-info/SOURCES.txt
psutil.egg-info/dependency_links.txt
psutil.egg-info/top_level.txt
psutil/arch/bsd/process_info.c
psutil/arch/bsd/process_info.h
psutil/arch/osx/process_info.c
psutil/arch/osx/process_info.h
psutil/arch/windows/glpi.h
psutil/arch/windows/inet_ntop.c
psutil/arch/windows/inet_ntop.h
psutil/arch/windows/ntextapi.h
psutil/arch/windows/process_handles.c
psutil/arch/windows/process_handles.h
psutil/arch/windows/process_info.c
psutil/arch/windows/process_info.h
psutil/arch/windows/security.c
psutil/arch/windows/security.h
test/README.rst
test/_bsd.py
test/_linux.py
test/_osx.py
test/_posix.py
test/_sunos.py
test/_windows.py
test/test_memory_leaks.py
test/test_psutil.py

Просмотреть файл

@ -1 +0,0 @@

Просмотреть файл

@ -1 +0,0 @@
psutil

5
third_party/python/psutil/psutil/DEVNOTES поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
API REFERENCES
==============
- psutil.sensors_battery:
https://github.com/Kentzo/Power/

1536
third_party/python/psutil/psutil/__init__.py поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

625
third_party/python/psutil/psutil/_common.py поставляемый
Просмотреть файл

@ -1,36 +1,95 @@
# /usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
"""Common objects shared by all _ps* modules.""" """Common objects shared by __init__.py and _ps*.py modules."""
# Note: this module is imported by setup.py so it should not import
# psutil or third-party modules.
from __future__ import division from __future__ import division
import contextlib
import errno import errno
import functools import functools
import os import os
import socket import socket
import stat import stat
import sys import sys
import threading
import warnings
from collections import defaultdict
from collections import namedtuple from collections import namedtuple
from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM from socket import AF_INET
from socket import SOCK_DGRAM
from socket import SOCK_STREAM
try: try:
import threading from socket import AF_INET6
except ImportError: except ImportError:
import dummy_threading as threading AF_INET6 = None
try:
from socket import AF_UNIX
except ImportError:
AF_UNIX = None
if sys.version_info >= (3, 4): if sys.version_info >= (3, 4):
import enum import enum
else: else:
enum = None enum = None
# can't take it from _common.py as this script is imported by setup.py
PY3 = sys.version_info[0] == 3
# --- constants __all__ = [
# constants
'FREEBSD', 'BSD', 'LINUX', 'NETBSD', 'OPENBSD', 'OSX', 'POSIX', 'SUNOS',
'WINDOWS',
'ENCODING', 'ENCODING_ERRS', 'AF_INET6',
# connection constants
'CONN_CLOSE', 'CONN_CLOSE_WAIT', 'CONN_CLOSING', 'CONN_ESTABLISHED',
'CONN_FIN_WAIT1', 'CONN_FIN_WAIT2', 'CONN_LAST_ACK', 'CONN_LISTEN',
'CONN_NONE', 'CONN_SYN_RECV', 'CONN_SYN_SENT', 'CONN_TIME_WAIT',
# net constants
'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN',
# process status constants
'STATUS_DEAD', 'STATUS_DISK_SLEEP', 'STATUS_IDLE', 'STATUS_LOCKED',
'STATUS_RUNNING', 'STATUS_SLEEPING', 'STATUS_STOPPED', 'STATUS_SUSPENDED',
'STATUS_TRACING_STOP', 'STATUS_WAITING', 'STATUS_WAKE_KILL',
'STATUS_WAKING', 'STATUS_ZOMBIE',
# named tuples
'pconn', 'pcputimes', 'pctxsw', 'pgids', 'pio', 'pionice', 'popenfile',
'pthread', 'puids', 'sconn', 'scpustats', 'sdiskio', 'sdiskpart',
'sdiskusage', 'snetio', 'snic', 'snicstats', 'sswap', 'suser',
# utility functions
'conn_tmap', 'deprecated_method', 'isfile_strict', 'memoize',
'parse_environ_block', 'path_exists_strict', 'usage_percent',
'supports_ipv6', 'sockfam_to_enum', 'socktype_to_enum', "wrap_numbers",
]
AF_INET6 = getattr(socket, 'AF_INET6', None)
AF_UNIX = getattr(socket, 'AF_UNIX', None)
# ===================================================================
# --- OS constants
# ===================================================================
POSIX = os.name == "posix"
WINDOWS = os.name == "nt"
LINUX = sys.platform.startswith("linux")
OSX = sys.platform.startswith("darwin")
FREEBSD = sys.platform.startswith("freebsd")
OPENBSD = sys.platform.startswith("openbsd")
NETBSD = sys.platform.startswith("netbsd")
BSD = FREEBSD or OPENBSD or NETBSD
SUNOS = sys.platform.startswith("sunos") or sys.platform.startswith("solaris")
AIX = sys.platform.startswith("aix")
# ===================================================================
# --- API constants
# ===================================================================
# Process.status()
STATUS_RUNNING = "running" STATUS_RUNNING = "running"
STATUS_SLEEPING = "sleeping" STATUS_SLEEPING = "sleeping"
STATUS_DISK_SLEEP = "disk-sleep" STATUS_DISK_SLEEP = "disk-sleep"
@ -40,10 +99,12 @@ STATUS_ZOMBIE = "zombie"
STATUS_DEAD = "dead" STATUS_DEAD = "dead"
STATUS_WAKE_KILL = "wake-kill" STATUS_WAKE_KILL = "wake-kill"
STATUS_WAKING = "waking" STATUS_WAKING = "waking"
STATUS_IDLE = "idle" # BSD STATUS_IDLE = "idle" # FreeBSD, OSX
STATUS_LOCKED = "locked" # BSD STATUS_LOCKED = "locked" # FreeBSD
STATUS_WAITING = "waiting" # BSD STATUS_WAITING = "waiting" # FreeBSD
STATUS_SUSPENDED = "suspended" # NetBSD
# Process.connections() and psutil.net_connections()
CONN_ESTABLISHED = "ESTABLISHED" CONN_ESTABLISHED = "ESTABLISHED"
CONN_SYN_SENT = "SYN_SENT" CONN_SYN_SENT = "SYN_SENT"
CONN_SYN_RECV = "SYN_RECV" CONN_SYN_RECV = "SYN_RECV"
@ -57,6 +118,7 @@ CONN_LISTEN = "LISTEN"
CONN_CLOSING = "CLOSING" CONN_CLOSING = "CLOSING"
CONN_NONE = "NONE" CONN_NONE = "NONE"
# net_if_stats()
if enum is None: if enum is None:
NIC_DUPLEX_FULL = 2 NIC_DUPLEX_FULL = 2
NIC_DUPLEX_HALF = 1 NIC_DUPLEX_HALF = 1
@ -69,102 +131,105 @@ else:
globals().update(NicDuplex.__members__) globals().update(NicDuplex.__members__)
# sensors_battery()
if enum is None:
POWER_TIME_UNKNOWN = -1
POWER_TIME_UNLIMITED = -2
else:
class BatteryTime(enum.IntEnum):
POWER_TIME_UNKNOWN = -1
POWER_TIME_UNLIMITED = -2
# --- functions globals().update(BatteryTime.__members__)
def usage_percent(used, total, _round=None): # --- others
"""Calculate percentage usage of 'used' against 'total'."""
ENCODING = sys.getfilesystemencoding()
if not PY3:
ENCODING_ERRS = "replace"
else:
try: try:
ret = (used / total) * 100 ENCODING_ERRS = sys.getfilesystemencodeerrors() # py 3.6
except ZeroDivisionError: except AttributeError:
ret = 0 ENCODING_ERRS = "surrogateescape" if POSIX else "replace"
if _round is not None:
return round(ret, _round)
else:
return ret
def memoize(fun): # ===================================================================
"""A simple memoize decorator for functions supporting (hashable) # --- namedtuples
positional arguments. # ===================================================================
It also provides a cache_clear() function for clearing the cache:
>>> @memoize # --- for system functions
... def foo()
... return 1
...
>>> foo()
1
>>> foo.cache_clear()
>>>
"""
@functools.wraps(fun)
def wrapper(*args, **kwargs):
key = (args, frozenset(sorted(kwargs.items())))
lock.acquire()
try:
try:
return cache[key]
except KeyError:
ret = cache[key] = fun(*args, **kwargs)
finally:
lock.release()
return ret
def cache_clear(): # psutil.swap_memory()
"""Clear cache.""" sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
lock.acquire() 'sout'])
try: # psutil.disk_usage()
cache.clear() sdiskusage = namedtuple('sdiskusage', ['total', 'used', 'free', 'percent'])
finally: # psutil.disk_io_counters()
lock.release() sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
'read_bytes', 'write_bytes',
'read_time', 'write_time'])
# psutil.disk_partitions()
sdiskpart = namedtuple('sdiskpart', ['device', 'mountpoint', 'fstype', 'opts'])
# psutil.net_io_counters()
snetio = namedtuple('snetio', ['bytes_sent', 'bytes_recv',
'packets_sent', 'packets_recv',
'errin', 'errout',
'dropin', 'dropout'])
# psutil.users()
suser = namedtuple('suser', ['name', 'terminal', 'host', 'started', 'pid'])
# psutil.net_connections()
sconn = namedtuple('sconn', ['fd', 'family', 'type', 'laddr', 'raddr',
'status', 'pid'])
# psutil.net_if_addrs()
snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast', 'ptp'])
# psutil.net_if_stats()
snicstats = namedtuple('snicstats', ['isup', 'duplex', 'speed', 'mtu'])
# psutil.cpu_stats()
scpustats = namedtuple(
'scpustats', ['ctx_switches', 'interrupts', 'soft_interrupts', 'syscalls'])
# psutil.cpu_freq()
scpufreq = namedtuple('scpufreq', ['current', 'min', 'max'])
# psutil.sensors_temperatures()
shwtemp = namedtuple(
'shwtemp', ['label', 'current', 'high', 'critical'])
# psutil.sensors_battery()
sbattery = namedtuple('sbattery', ['percent', 'secsleft', 'power_plugged'])
# psutil.sensors_battery()
sfan = namedtuple('sfan', ['label', 'current'])
lock = threading.RLock() # --- for Process methods
cache = {}
wrapper.cache_clear = cache_clear # psutil.Process.cpu_times()
return wrapper pcputimes = namedtuple('pcputimes',
['user', 'system', 'children_user', 'children_system'])
# psutil.Process.open_files()
def isfile_strict(path): popenfile = namedtuple('popenfile', ['path', 'fd'])
"""Same as os.path.isfile() but does not swallow EACCES / EPERM # psutil.Process.threads()
exceptions, see: pthread = namedtuple('pthread', ['id', 'user_time', 'system_time'])
http://mail.python.org/pipermail/python-dev/2012-June/120787.html # psutil.Process.uids()
""" puids = namedtuple('puids', ['real', 'effective', 'saved'])
try: # psutil.Process.gids()
st = os.stat(path) pgids = namedtuple('pgids', ['real', 'effective', 'saved'])
except OSError as err: # psutil.Process.io_counters()
if err.errno in (errno.EPERM, errno.EACCES): pio = namedtuple('pio', ['read_count', 'write_count',
raise 'read_bytes', 'write_bytes'])
return False # psutil.Process.ionice()
else: pionice = namedtuple('pionice', ['ioclass', 'value'])
return stat.S_ISREG(st.st_mode) # psutil.Process.ctx_switches()
pctxsw = namedtuple('pctxsw', ['voluntary', 'involuntary'])
# psutil.Process.connections()
def sockfam_to_enum(num): pconn = namedtuple('pconn', ['fd', 'family', 'type', 'laddr', 'raddr',
"""Convert a numeric socket family value to an IntEnum member. 'status'])
If it's not a known member, return the numeric value itself.
""" # psutil.connections() and psutil.Process.connections()
if enum is None: addr = namedtuple('addr', ['ip', 'port'])
return num
try:
return socket.AddressFamily(num)
except (ValueError, AttributeError):
return num
def socktype_to_enum(num):
"""Convert a numeric socket type value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
if enum is None:
return num
try:
return socket.AddressType(num)
except (ValueError, AttributeError):
return num
# ===================================================================
# --- Process.connections() 'kind' parameter mapping # --- Process.connections() 'kind' parameter mapping
# ===================================================================
conn_tmap = { conn_tmap = {
"all": ([AF_INET, AF_INET6, AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]), "all": ([AF_INET, AF_INET6, AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
@ -188,59 +253,323 @@ if AF_UNIX is not None:
"unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]), "unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM]),
}) })
del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM del AF_INET, AF_UNIX, SOCK_STREAM, SOCK_DGRAM
# --- namedtuples for psutil.* system-related functions # ===================================================================
# --- utils
# psutil.swap_memory() # ===================================================================
sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
'sout'])
# psutil.disk_usage()
sdiskusage = namedtuple('sdiskusage', ['total', 'used', 'free', 'percent'])
# psutil.disk_io_counters()
sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
'read_bytes', 'write_bytes',
'read_time', 'write_time'])
# psutil.disk_partitions()
sdiskpart = namedtuple('sdiskpart', ['device', 'mountpoint', 'fstype', 'opts'])
# psutil.net_io_counters()
snetio = namedtuple('snetio', ['bytes_sent', 'bytes_recv',
'packets_sent', 'packets_recv',
'errin', 'errout',
'dropin', 'dropout'])
# psutil.users()
suser = namedtuple('suser', ['name', 'terminal', 'host', 'started'])
# psutil.net_connections()
sconn = namedtuple('sconn', ['fd', 'family', 'type', 'laddr', 'raddr',
'status', 'pid'])
# psutil.net_if_addrs()
snic = namedtuple('snic', ['family', 'address', 'netmask', 'broadcast'])
# psutil.net_if_stats()
snicstats = namedtuple('snicstats', ['isup', 'duplex', 'speed', 'mtu'])
# --- namedtuples for psutil.Process methods def usage_percent(used, total, _round=None):
"""Calculate percentage usage of 'used' against 'total'."""
try:
ret = (used / total) * 100
except ZeroDivisionError:
ret = 0.0 if isinstance(used, float) or isinstance(total, float) else 0
if _round is not None:
return round(ret, _round)
else:
return ret
# psutil.Process.memory_info()
pmem = namedtuple('pmem', ['rss', 'vms']) def memoize(fun):
# psutil.Process.cpu_times() """A simple memoize decorator for functions supporting (hashable)
pcputimes = namedtuple('pcputimes', ['user', 'system']) positional arguments.
# psutil.Process.open_files() It also provides a cache_clear() function for clearing the cache:
popenfile = namedtuple('popenfile', ['path', 'fd'])
# psutil.Process.threads() >>> @memoize
pthread = namedtuple('pthread', ['id', 'user_time', 'system_time']) ... def foo()
# psutil.Process.uids() ... return 1
puids = namedtuple('puids', ['real', 'effective', 'saved']) ...
# psutil.Process.gids() >>> foo()
pgids = namedtuple('pgids', ['real', 'effective', 'saved']) 1
# psutil.Process.io_counters() >>> foo.cache_clear()
pio = namedtuple('pio', ['read_count', 'write_count', >>>
'read_bytes', 'write_bytes']) """
# psutil.Process.ionice() @functools.wraps(fun)
pionice = namedtuple('pionice', ['ioclass', 'value']) def wrapper(*args, **kwargs):
# psutil.Process.ctx_switches() key = (args, frozenset(sorted(kwargs.items())))
pctxsw = namedtuple('pctxsw', ['voluntary', 'involuntary']) try:
# psutil.Process.connections() return cache[key]
pconn = namedtuple('pconn', ['fd', 'family', 'type', 'laddr', 'raddr', except KeyError:
'status']) ret = cache[key] = fun(*args, **kwargs)
return ret
def cache_clear():
"""Clear cache."""
cache.clear()
cache = {}
wrapper.cache_clear = cache_clear
return wrapper
def memoize_when_activated(fun):
"""A memoize decorator which is disabled by default. It can be
activated and deactivated on request.
For efficiency reasons it can be used only against class methods
accepting no arguments.
>>> class Foo:
... @memoize
... def foo()
... print(1)
...
>>> f = Foo()
>>> # deactivated (default)
>>> foo()
1
>>> foo()
1
>>>
>>> # activated
>>> foo.cache_activate()
>>> foo()
1
>>> foo()
>>> foo()
>>>
"""
@functools.wraps(fun)
def wrapper(self):
if not wrapper.cache_activated:
return fun(self)
else:
try:
ret = cache[fun]
except KeyError:
ret = cache[fun] = fun(self)
return ret
def cache_activate():
"""Activate cache."""
wrapper.cache_activated = True
def cache_deactivate():
"""Deactivate and clear cache."""
wrapper.cache_activated = False
cache.clear()
cache = {}
wrapper.cache_activated = False
wrapper.cache_activate = cache_activate
wrapper.cache_deactivate = cache_deactivate
return wrapper
def isfile_strict(path):
"""Same as os.path.isfile() but does not swallow EACCES / EPERM
exceptions, see:
http://mail.python.org/pipermail/python-dev/2012-June/120787.html
"""
try:
st = os.stat(path)
except OSError as err:
if err.errno in (errno.EPERM, errno.EACCES):
raise
return False
else:
return stat.S_ISREG(st.st_mode)
def path_exists_strict(path):
"""Same as os.path.exists() but does not swallow EACCES / EPERM
exceptions, see:
http://mail.python.org/pipermail/python-dev/2012-June/120787.html
"""
try:
os.stat(path)
except OSError as err:
if err.errno in (errno.EPERM, errno.EACCES):
raise
return False
else:
return True
@memoize
def supports_ipv6():
"""Return True if IPv6 is supported on this platform."""
if not socket.has_ipv6 or AF_INET6 is None:
return False
try:
sock = socket.socket(AF_INET6, socket.SOCK_STREAM)
with contextlib.closing(sock):
sock.bind(("::1", 0))
return True
except socket.error:
return False
def parse_environ_block(data):
"""Parse a C environ block of environment variables into a dictionary."""
# The block is usually raw data from the target process. It might contain
# trailing garbage and lines that do not look like assignments.
ret = {}
pos = 0
# localize global variable to speed up access.
WINDOWS_ = WINDOWS
while True:
next_pos = data.find("\0", pos)
# nul byte at the beginning or double nul byte means finish
if next_pos <= pos:
break
# there might not be an equals sign
equal_pos = data.find("=", pos, next_pos)
if equal_pos > pos:
key = data[pos:equal_pos]
value = data[equal_pos + 1:next_pos]
# Windows expects environment variables to be uppercase only
if WINDOWS_:
key = key.upper()
ret[key] = value
pos = next_pos + 1
return ret
def sockfam_to_enum(num):
"""Convert a numeric socket family value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
if enum is None:
return num
else: # pragma: no cover
try:
return socket.AddressFamily(num)
except (ValueError, AttributeError):
return num
def socktype_to_enum(num):
"""Convert a numeric socket type value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
if enum is None:
return num
else: # pragma: no cover
try:
return socket.AddressType(num)
except (ValueError, AttributeError):
return num
def deprecated_method(replacement):
"""A decorator which can be used to mark a method as deprecated
'replcement' is the method name which will be called instead.
"""
def outer(fun):
msg = "%s() is deprecated and will be removed; use %s() instead" % (
fun.__name__, replacement)
if fun.__doc__ is None:
fun.__doc__ = msg
@functools.wraps(fun)
def inner(self, *args, **kwargs):
warnings.warn(msg, category=FutureWarning, stacklevel=2)
return getattr(self, replacement)(*args, **kwargs)
return inner
return outer
class _WrapNumbers:
"""Watches numbers so that they don't overflow and wrap
(reset to zero).
"""
def __init__(self):
self.lock = threading.Lock()
self.cache = {}
self.reminders = {}
self.reminder_keys = {}
def _add_dict(self, input_dict, name):
assert name not in self.cache
assert name not in self.reminders
assert name not in self.reminder_keys
self.cache[name] = input_dict
self.reminders[name] = defaultdict(int)
self.reminder_keys[name] = defaultdict(set)
def _remove_dead_reminders(self, input_dict, name):
"""In case the number of keys changed between calls (e.g. a
disk disappears) this removes the entry from self.reminders.
"""
old_dict = self.cache[name]
gone_keys = set(old_dict.keys()) - set(input_dict.keys())
for gone_key in gone_keys:
for remkey in self.reminder_keys[name][gone_key]:
del self.reminders[name][remkey]
del self.reminder_keys[name][gone_key]
def run(self, input_dict, name):
"""Cache dict and sum numbers which overflow and wrap.
Return an updated copy of `input_dict`
"""
if name not in self.cache:
# This was the first call.
self._add_dict(input_dict, name)
return input_dict
self._remove_dead_reminders(input_dict, name)
old_dict = self.cache[name]
new_dict = {}
for key in input_dict.keys():
input_tuple = input_dict[key]
try:
old_tuple = old_dict[key]
except KeyError:
# The input dict has a new key (e.g. a new disk or NIC)
# which didn't exist in the previous call.
new_dict[key] = input_tuple
continue
bits = []
for i in range(len(input_tuple)):
input_value = input_tuple[i]
old_value = old_tuple[i]
remkey = (key, i)
if input_value < old_value:
# it wrapped!
self.reminders[name][remkey] += old_value
self.reminder_keys[name][key].add(remkey)
bits.append(input_value + self.reminders[name][remkey])
new_dict[key] = tuple(bits)
self.cache[name] = input_dict
return new_dict
def cache_clear(self, name=None):
"""Clear the internal cache, optionally only for function 'name'."""
with self.lock:
if name is None:
self.cache.clear()
self.reminders.clear()
self.reminder_keys.clear()
else:
self.cache.pop(name, None)
self.reminders.pop(name, None)
self.reminder_keys.pop(name, None)
def cache_info(self):
"""Return internal cache dicts as a tuple of 3 elements."""
with self.lock:
return (self.cache, self.reminders, self.reminder_keys)
def wrap_numbers(input_dict, name):
"""Given an `input_dict` and a function `name`, adjust the numbers
which "wrap" (restart from zero) across different calls by adding
"old value" to "new value" and return an updated dict.
"""
with _wn.lock:
return _wn.run(input_dict, name)
_wn = _WrapNumbers()
wrap_numbers.cache_clear = _wn.cache_clear
wrap_numbers.cache_info = _wn.cache_info

66
third_party/python/psutil/psutil/_compat.py поставляемый
Просмотреть файл

@ -1,5 +1,3 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -8,9 +6,11 @@
import collections import collections
import functools import functools
import os
import sys import sys
__all__ = ["PY3", "long", "xrange", "unicode", "callable", "lru_cache"] __all__ = ["PY3", "long", "xrange", "unicode", "basestring", "u", "b",
"callable", "lru_cache", "which"]
PY3 = sys.version_info[0] == 3 PY3 = sys.version_info[0] == 3
@ -18,17 +18,25 @@ if PY3:
long = int long = int
xrange = range xrange = range
unicode = str unicode = str
basestring = str
def u(s): def u(s):
return s return s
def b(s):
return s.encode("latin-1")
else: else:
long = long long = long
xrange = xrange xrange = xrange
unicode = unicode unicode = unicode
basestring = basestring
def u(s): def u(s):
return unicode(s, "unicode_escape") return unicode(s, "unicode_escape")
def b(s):
return s
# removed in 3.0, reintroduced in 3.2 # removed in 3.0, reintroduced in 3.2
try: try:
@ -187,3 +195,55 @@ except ImportError:
return functools.update_wrapper(wrapper, user_function) return functools.update_wrapper(wrapper, user_function)
return decorating_function return decorating_function
# python 3.3
try:
from shutil import which
except ImportError:
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
"""Given a command, mode, and a PATH string, return the path which
conforms to the given mode on the PATH, or None if there is no such
file.
`mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
of os.environ.get("PATH"), or can be overridden with a custom search
path.
"""
def _access_check(fn, mode):
return (os.path.exists(fn) and os.access(fn, mode) and
not os.path.isdir(fn))
if os.path.dirname(cmd):
if _access_check(cmd, mode):
return cmd
return None
if path is None:
path = os.environ.get("PATH", os.defpath)
if not path:
return None
path = path.split(os.pathsep)
if sys.platform == "win32":
if os.curdir not in path:
path.insert(0, os.curdir)
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
files = [cmd]
else:
files = [cmd + ext for ext in pathext]
else:
files = [cmd]
seen = set()
for dir in path:
normdir = os.path.normcase(dir)
if normdir not in seen:
seen.add(normdir)
for thefile in files:
name = os.path.join(dir, thefile)
if _access_check(name, mode):
return name
return None

94
third_party/python/psutil/psutil/_exceptions.py поставляемый Normal file
Просмотреть файл

@ -0,0 +1,94 @@
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
class Error(Exception):
"""Base exception class. All other psutil exceptions inherit
from this one.
"""
def __init__(self, msg=""):
Exception.__init__(self, msg)
self.msg = msg
def __repr__(self):
ret = "psutil.%s %s" % (self.__class__.__name__, self.msg)
return ret.strip()
__str__ = __repr__
class NoSuchProcess(Error):
"""Exception raised when a process with a certain PID doesn't
or no longer exists.
"""
def __init__(self, pid, name=None, msg=None):
Error.__init__(self, msg)
self.pid = pid
self.name = name
self.msg = msg
if msg is None:
if name:
details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
else:
details = "(pid=%s)" % self.pid
self.msg = "process no longer exists " + details
class ZombieProcess(NoSuchProcess):
"""Exception raised when querying a zombie process. This is
raised on OSX, BSD and Solaris only, and not always: depending
on the query the OS may be able to succeed anyway.
On Linux all zombie processes are querable (hence this is never
raised). Windows doesn't have zombie processes.
"""
def __init__(self, pid, name=None, ppid=None, msg=None):
NoSuchProcess.__init__(self, msg)
self.pid = pid
self.ppid = ppid
self.name = name
self.msg = msg
if msg is None:
args = ["pid=%s" % pid]
if name:
args.append("name=%s" % repr(self.name))
if ppid:
args.append("ppid=%s" % self.ppid)
details = "(%s)" % ", ".join(args)
self.msg = "process still exists but it's a zombie " + details
class AccessDenied(Error):
"""Exception raised when permission to perform an action is denied."""
def __init__(self, pid=None, name=None, msg=None):
Error.__init__(self, msg)
self.pid = pid
self.name = name
self.msg = msg
if msg is None:
if (pid is not None) and (name is not None):
self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
elif (pid is not None):
self.msg = "(pid=%s)" % self.pid
else:
self.msg = ""
class TimeoutExpired(Error):
"""Raised on Process.wait(timeout) if timeout expires and process
is still alive.
"""
def __init__(self, seconds, pid=None, name=None):
Error.__init__(self, "timeout after %s seconds" % seconds)
self.seconds = seconds
self.pid = pid
self.name = name
if (pid is not None) and (name is not None):
self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
elif (pid is not None):
self.msg += " (pid=%s)" % self.pid

573
third_party/python/psutil/psutil/_psaix.py поставляемый Normal file
Просмотреть файл

@ -0,0 +1,573 @@
# Copyright (c) 2009, Giampaolo Rodola'
# Copyright (c) 2017, Arnon Yaari
# All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""AIX platform implementation."""
import errno
import glob
import os
import re
import subprocess
import sys
from collections import namedtuple
from socket import AF_INET
from . import _common
from . import _psposix
from . import _psutil_aix as cext
from . import _psutil_posix as cext_posix
from ._common import AF_INET6
from ._common import memoize_when_activated
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import PY3
from ._exceptions import AccessDenied
from ._exceptions import NoSuchProcess
from ._exceptions import ZombieProcess
__extra__all__ = ["PROCFS_PATH"]
# =====================================================================
# --- globals
# =====================================================================
HAS_THREADS = hasattr(cext, "proc_threads")
PAGE_SIZE = os.sysconf('SC_PAGE_SIZE')
AF_LINK = cext_posix.AF_LINK
PROC_STATUSES = {
cext.SIDL: _common.STATUS_IDLE,
cext.SZOMB: _common.STATUS_ZOMBIE,
cext.SACTIVE: _common.STATUS_RUNNING,
cext.SSWAP: _common.STATUS_RUNNING, # TODO what status is this?
cext.SSTOP: _common.STATUS_STOPPED,
}
TCP_STATUSES = {
cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
cext.TCPS_SYN_RCVD: _common.CONN_SYN_RECV,
cext.TCPS_FIN_WAIT_1: _common.CONN_FIN_WAIT1,
cext.TCPS_FIN_WAIT_2: _common.CONN_FIN_WAIT2,
cext.TCPS_TIME_WAIT: _common.CONN_TIME_WAIT,
cext.TCPS_CLOSED: _common.CONN_CLOSE,
cext.TCPS_CLOSE_WAIT: _common.CONN_CLOSE_WAIT,
cext.TCPS_LAST_ACK: _common.CONN_LAST_ACK,
cext.TCPS_LISTEN: _common.CONN_LISTEN,
cext.TCPS_CLOSING: _common.CONN_CLOSING,
cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
}
proc_info_map = dict(
ppid=0,
rss=1,
vms=2,
create_time=3,
nice=4,
num_threads=5,
status=6,
ttynr=7)
# =====================================================================
# --- named tuples
# =====================================================================
# psutil.Process.memory_info()
pmem = namedtuple('pmem', ['rss', 'vms'])
# psutil.Process.memory_full_info()
pfullmem = pmem
# psutil.Process.cpu_times()
scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait'])
# psutil.virtual_memory()
svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
# psutil.Process.memory_maps(grouped=True)
pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss', 'anon', 'locked'])
# psutil.Process.memory_maps(grouped=False)
pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
# =====================================================================
# --- utils
# =====================================================================
def get_procfs_path():
"""Return updated psutil.PROCFS_PATH constant."""
return sys.modules['psutil'].PROCFS_PATH
# =====================================================================
# --- memory
# =====================================================================
def virtual_memory():
total, avail, free, pinned, inuse = cext.virtual_mem()
percent = usage_percent((total - avail), total, _round=1)
return svmem(total, avail, percent, inuse, free)
def swap_memory():
"""Swap system memory as a (total, used, free, sin, sout) tuple."""
total, free, sin, sout = cext.swap_mem()
used = total - free
percent = usage_percent(used, total, _round=1)
return _common.sswap(total, used, free, percent, sin, sout)
# =====================================================================
# --- CPU
# =====================================================================
def cpu_times():
"""Return system-wide CPU times as a named tuple"""
ret = cext.per_cpu_times()
return scputimes(*[sum(x) for x in zip(*ret)])
def per_cpu_times():
"""Return system per-CPU times as a list of named tuples"""
ret = cext.per_cpu_times()
return [scputimes(*x) for x in ret]
def cpu_count_logical():
"""Return the number of logical CPUs in the system."""
try:
return os.sysconf("SC_NPROCESSORS_ONLN")
except ValueError:
# mimic os.cpu_count() behavior
return None
def cpu_count_physical():
cmd = "lsdev -Cc processor"
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if PY3:
stdout, stderr = [x.decode(sys.stdout.encoding)
for x in (stdout, stderr)]
if p.returncode != 0:
raise RuntimeError("%r command error\n%s" % (cmd, stderr))
processors = stdout.strip().splitlines()
return len(processors) or None
def cpu_stats():
"""Return various CPU stats as a named tuple."""
ctx_switches, interrupts, soft_interrupts, syscalls = cext.cpu_stats()
return _common.scpustats(
ctx_switches, interrupts, soft_interrupts, syscalls)
# =====================================================================
# --- disks
# =====================================================================
disk_io_counters = cext.disk_io_counters
disk_usage = _psposix.disk_usage
def disk_partitions(all=False):
"""Return system disk partitions."""
# TODO - the filtering logic should be better checked so that
# it tries to reflect 'df' as much as possible
retlist = []
partitions = cext.disk_partitions()
for partition in partitions:
device, mountpoint, fstype, opts = partition
if device == 'none':
device = ''
if not all:
# Differently from, say, Linux, we don't have a list of
# common fs types so the best we can do, AFAIK, is to
# filter by filesystem having a total size > 0.
if not disk_usage(mountpoint).total:
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple)
return retlist
# =====================================================================
# --- network
# =====================================================================
net_if_addrs = cext_posix.net_if_addrs
net_io_counters = cext.net_io_counters
def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only).
"""
cmap = _common.conn_tmap
if kind not in cmap:
raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in cmap])))
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid)
ret = set()
for item in rawlist:
fd, fam, type_, laddr, raddr, status, pid = item
if fam not in families:
continue
if type_ not in types:
continue
status = TCP_STATUSES[status]
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
fam = sockfam_to_enum(fam)
type_ = socktype_to_enum(type_)
if _pid == -1:
nt = _common.sconn(fd, fam, type_, laddr, raddr, status, pid)
else:
nt = _common.pconn(fd, fam, type_, laddr, raddr, status)
ret.add(nt)
return list(ret)
def net_if_stats():
"""Get NIC stats (isup, duplex, speed, mtu)."""
duplex_map = {"Full": NIC_DUPLEX_FULL,
"Half": NIC_DUPLEX_HALF}
names = set([x[0] for x in net_if_addrs()])
ret = {}
for name in names:
isup, mtu = cext.net_if_stats(name)
# try to get speed and duplex
# TODO: rewrite this in C (entstat forks, so use truss -f to follow.
# looks like it is using an undocumented ioctl?)
duplex = ""
speed = 0
p = subprocess.Popen(["/usr/bin/entstat", "-d", name],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if PY3:
stdout, stderr = [x.decode(sys.stdout.encoding)
for x in (stdout, stderr)]
if p.returncode == 0:
re_result = re.search("Running: (\d+) Mbps.*?(\w+) Duplex", stdout)
if re_result is not None:
speed = int(re_result.group(1))
duplex = re_result.group(2)
duplex = duplex_map.get(duplex, NIC_DUPLEX_UNKNOWN)
ret[name] = _common.snicstats(isup, duplex, speed, mtu)
return ret
# =====================================================================
# --- other system functions
# =====================================================================
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
return cext.boot_time()
def users():
"""Return currently connected users as a list of namedtuples."""
retlist = []
rawlist = cext.users()
localhost = (':0.0', ':0')
for item in rawlist:
user, tty, hostname, tstamp, user_process, pid = item
# note: the underlying C function includes entries about
# system boot, run level and others. We might want
# to use them in the future.
if not user_process:
continue
if hostname in localhost:
hostname = 'localhost'
nt = _common.suser(user, tty, hostname, tstamp, pid)
retlist.append(nt)
return retlist
# =====================================================================
# --- processes
# =====================================================================
def pids():
"""Returns a list of PIDs currently running on the system."""
return [int(x) for x in os.listdir(get_procfs_path()) if x.isdigit()]
def pid_exists(pid):
"""Check for the existence of a unix pid."""
return os.path.exists(os.path.join(get_procfs_path(), str(pid), "psinfo"))
def wrap_exceptions(fun):
"""Call callable into a try/except clause and translate ENOENT,
EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
"""
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except EnvironmentError as err:
# support for private module import
if (NoSuchProcess is None or AccessDenied is None or
ZombieProcess is None):
raise
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if err.errno in (errno.ENOENT, errno.ESRCH):
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
class Process(object):
"""Wrapper class around underlying C implementation."""
__slots__ = ["pid", "_name", "_ppid", "_procfs_path"]
def __init__(self, pid):
self.pid = pid
self._name = None
self._ppid = None
self._procfs_path = get_procfs_path()
def oneshot_enter(self):
self._proc_name_and_args.cache_activate()
self._proc_basic_info.cache_activate()
self._proc_cred.cache_activate()
def oneshot_exit(self):
self._proc_name_and_args.cache_deactivate()
self._proc_basic_info.cache_deactivate()
self._proc_cred.cache_deactivate()
@memoize_when_activated
def _proc_name_and_args(self):
return cext.proc_name_and_args(self.pid, self._procfs_path)
@memoize_when_activated
def _proc_basic_info(self):
return cext.proc_basic_info(self.pid, self._procfs_path)
@memoize_when_activated
def _proc_cred(self):
return cext.proc_cred(self.pid, self._procfs_path)
@wrap_exceptions
def name(self):
if self.pid == 0:
return "swapper"
# note: this is limited to 15 characters
return self._proc_name_and_args()[0].rstrip("\x00")
@wrap_exceptions
def exe(self):
# there is no way to get executable path in AIX other than to guess,
# and guessing is more complex than what's in the wrapping class
exe = self.cmdline()[0]
if os.path.sep in exe:
# relative or absolute path
if not os.path.isabs(exe):
# if cwd has changed, we're out of luck - this may be wrong!
exe = os.path.abspath(os.path.join(self.cwd(), exe))
if (os.path.isabs(exe) and
os.path.isfile(exe) and
os.access(exe, os.X_OK)):
return exe
# not found, move to search in PATH using basename only
exe = os.path.basename(exe)
# search for exe name PATH
for path in os.environ["PATH"].split(":"):
possible_exe = os.path.abspath(os.path.join(path, exe))
if (os.path.isfile(possible_exe) and
os.access(possible_exe, os.X_OK)):
return possible_exe
return ''
@wrap_exceptions
def cmdline(self):
return self._proc_name_and_args()[1].split(' ')
@wrap_exceptions
def create_time(self):
return self._proc_basic_info()[proc_info_map['create_time']]
@wrap_exceptions
def num_threads(self):
return self._proc_basic_info()[proc_info_map['num_threads']]
if HAS_THREADS:
@wrap_exceptions
def threads(self):
rawlist = cext.proc_threads(self.pid)
retlist = []
for thread_id, utime, stime in rawlist:
ntuple = _common.pthread(thread_id, utime, stime)
retlist.append(ntuple)
# The underlying C implementation retrieves all OS threads
# and filters them by PID. At this point we can't tell whether
# an empty list means there were no connections for process or
# process is no longer active so we force NSP in case the PID
# is no longer there.
if not retlist:
# will raise NSP if process is gone
os.stat('%s/%s' % (self._procfs_path, self.pid))
return retlist
@wrap_exceptions
def connections(self, kind='inet'):
ret = net_connections(kind, _pid=self.pid)
# The underlying C implementation retrieves all OS connections
# and filters them by PID. At this point we can't tell whether
# an empty list means there were no connections for process or
# process is no longer active so we force NSP in case the PID
# is no longer there.
if not ret:
# will raise NSP if process is gone
os.stat('%s/%s' % (self._procfs_path, self.pid))
return ret
@wrap_exceptions
def nice_get(self):
return cext_posix.getpriority(self.pid)
@wrap_exceptions
def nice_set(self, value):
return cext_posix.setpriority(self.pid, value)
@wrap_exceptions
def ppid(self):
self._ppid = self._proc_basic_info()[proc_info_map['ppid']]
return self._ppid
@wrap_exceptions
def uids(self):
real, effective, saved, _, _, _ = self._proc_cred()
return _common.puids(real, effective, saved)
@wrap_exceptions
def gids(self):
_, _, _, real, effective, saved = self._proc_cred()
return _common.puids(real, effective, saved)
@wrap_exceptions
def cpu_times(self):
cpu_times = cext.proc_cpu_times(self.pid, self._procfs_path)
return _common.pcputimes(*cpu_times)
@wrap_exceptions
def terminal(self):
ttydev = self._proc_basic_info()[proc_info_map['ttynr']]
# convert from 64-bit dev_t to 32-bit dev_t and then map the device
ttydev = (((ttydev & 0x0000FFFF00000000) >> 16) | (ttydev & 0xFFFF))
# try to match rdev of /dev/pts/* files ttydev
for dev in glob.glob("/dev/**/*"):
if os.stat(dev).st_rdev == ttydev:
return dev
return None
@wrap_exceptions
def cwd(self):
procfs_path = self._procfs_path
try:
result = os.readlink("%s/%s/cwd" % (procfs_path, self.pid))
return result.rstrip('/')
except OSError as err:
if err.errno == errno.ENOENT:
os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
return None
raise
@wrap_exceptions
def memory_info(self):
ret = self._proc_basic_info()
rss = ret[proc_info_map['rss']] * 1024
vms = ret[proc_info_map['vms']] * 1024
return pmem(rss, vms)
memory_full_info = memory_info
@wrap_exceptions
def status(self):
code = self._proc_basic_info()[proc_info_map['status']]
# XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES.get(code, '?')
def open_files(self):
# TODO rewrite without using procfiles (stat /proc/pid/fd/* and then
# find matching name of the inode)
p = subprocess.Popen(["/usr/bin/procfiles", "-n", str(self.pid)],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if PY3:
stdout, stderr = [x.decode(sys.stdout.encoding)
for x in (stdout, stderr)]
if "no such process" in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
procfiles = re.findall("(\d+): S_IFREG.*\s*.*name:(.*)\n", stdout)
retlist = []
for fd, path in procfiles:
path = path.strip()
if path.startswith("//"):
path = path[1:]
if path.lower() == "cannot be retrieved":
continue
retlist.append(_common.popenfile(path, int(fd)))
return retlist
@wrap_exceptions
def num_fds(self):
if self.pid == 0: # no /proc/0/fd
return 0
return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
@wrap_exceptions
def num_ctx_switches(self):
return _common.pctxsw(
*cext.proc_num_ctx_switches(self.pid))
@wrap_exceptions
def wait(self, timeout=None):
return _psposix.wait_pid(self.pid, timeout, self._name)
@wrap_exceptions
def io_counters(self):
try:
rc, wc, rb, wb = cext.proc_io_counters(self.pid)
except OSError:
# if process is terminated, proc_io_counters returns OSError
# instead of NSP
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
raise
return _common.pio(rc, wc, rb, wb)

758
third_party/python/psutil/psutil/_psbsd.py поставляемый
Просмотреть файл

@ -1,38 +1,86 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
"""FreeBSD platform implementation.""" """FreeBSD, OpenBSD and NetBSD platforms implementation."""
import contextlib
import errno import errno
import functools import functools
import os import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from collections import namedtuple from collections import namedtuple
from socket import AF_INET
from . import _common from . import _common
from . import _psposix from . import _psposix
from . import _psutil_bsd as cext from . import _psutil_bsd as cext
from . import _psutil_posix as cext_posix from . import _psutil_posix as cext_posix
from ._common import conn_tmap, usage_percent, sockfam_to_enum from ._common import AF_INET6
from ._common import conn_tmap
from ._common import FREEBSD
from ._common import memoize
from ._common import memoize_when_activated
from ._common import NETBSD
from ._common import OPENBSD
from ._common import sockfam_to_enum
from ._common import socktype_to_enum from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import which
from ._exceptions import AccessDenied
from ._exceptions import NoSuchProcess
from ._exceptions import ZombieProcess
__extra__all__ = [] __extra__all__ = []
# --- constants
PROC_STATUSES = { # =====================================================================
cext.SSTOP: _common.STATUS_STOPPED, # --- globals
cext.SSLEEP: _common.STATUS_SLEEPING, # =====================================================================
cext.SRUN: _common.STATUS_RUNNING,
cext.SIDL: _common.STATUS_IDLE,
cext.SWAIT: _common.STATUS_WAITING, if FREEBSD:
cext.SLOCK: _common.STATUS_LOCKED, PROC_STATUSES = {
cext.SZOMB: _common.STATUS_ZOMBIE, cext.SIDL: _common.STATUS_IDLE,
} cext.SRUN: _common.STATUS_RUNNING,
cext.SSLEEP: _common.STATUS_SLEEPING,
cext.SSTOP: _common.STATUS_STOPPED,
cext.SZOMB: _common.STATUS_ZOMBIE,
cext.SWAIT: _common.STATUS_WAITING,
cext.SLOCK: _common.STATUS_LOCKED,
}
elif OPENBSD or NETBSD:
PROC_STATUSES = {
cext.SIDL: _common.STATUS_IDLE,
cext.SSLEEP: _common.STATUS_SLEEPING,
cext.SSTOP: _common.STATUS_STOPPED,
# According to /usr/include/sys/proc.h SZOMB is unused.
# test_zombie_process() shows that SDEAD is the right
# equivalent. Also it appears there's no equivalent of
# psutil.STATUS_DEAD. SDEAD really means STATUS_ZOMBIE.
# cext.SZOMB: _common.STATUS_ZOMBIE,
cext.SDEAD: _common.STATUS_ZOMBIE,
cext.SZOMB: _common.STATUS_ZOMBIE,
# From http://www.eecs.harvard.edu/~margo/cs161/videos/proc.h.txt
# OpenBSD has SRUN and SONPROC: SRUN indicates that a process
# is runnable but *not* yet running, i.e. is on a run queue.
# SONPROC indicates that the process is actually executing on
# a CPU, i.e. it is no longer on a run queue.
# As such we'll map SRUN to STATUS_WAKING and SONPROC to
# STATUS_RUNNING
cext.SRUN: _common.STATUS_WAKING,
cext.SONPROC: _common.STATUS_RUNNING,
}
elif NETBSD:
PROC_STATUSES = {
cext.SIDL: _common.STATUS_IDLE,
cext.SACTIVE: _common.STATUS_RUNNING,
cext.SDYING: _common.STATUS_ZOMBIE,
cext.SSTOP: _common.STATUS_STOPPED,
cext.SZOMB: _common.STATUS_ZOMBIE,
cext.SDEAD: _common.STATUS_DEAD,
cext.SSUSPENDED: _common.STATUS_SUSPENDED, # unique to NetBSD
}
TCP_STATUSES = { TCP_STATUSES = {
cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
@ -49,32 +97,95 @@ TCP_STATUSES = {
cext.PSUTIL_CONN_NONE: _common.CONN_NONE, cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
} }
PAGESIZE = os.sysconf("SC_PAGE_SIZE") if NETBSD:
PAGESIZE = os.sysconf("SC_PAGESIZE")
else:
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
AF_LINK = cext_posix.AF_LINK AF_LINK = cext_posix.AF_LINK
# extend base mem ntuple with BSD-specific memory metrics kinfo_proc_map = dict(
ppid=0,
status=1,
real_uid=2,
effective_uid=3,
saved_uid=4,
real_gid=5,
effective_gid=6,
saved_gid=7,
ttynr=8,
create_time=9,
ctx_switches_vol=10,
ctx_switches_unvol=11,
read_io_count=12,
write_io_count=13,
user_time=14,
sys_time=15,
ch_user_time=16,
ch_sys_time=17,
rss=18,
vms=19,
memtext=20,
memdata=21,
memstack=22,
cpunum=23,
name=24,
)
# =====================================================================
# --- named tuples
# =====================================================================
# psutil.virtual_memory()
svmem = namedtuple( svmem = namedtuple(
'svmem', ['total', 'available', 'percent', 'used', 'free', 'svmem', ['total', 'available', 'percent', 'used', 'free',
'active', 'inactive', 'buffers', 'cached', 'shared', 'wired']) 'active', 'inactive', 'buffers', 'cached', 'shared', 'wired'])
# psutil.cpu_times()
scputimes = namedtuple( scputimes = namedtuple(
'scputimes', ['user', 'nice', 'system', 'idle', 'irq']) 'scputimes', ['user', 'nice', 'system', 'idle', 'irq'])
pextmem = namedtuple('pextmem', ['rss', 'vms', 'text', 'data', 'stack']) # psutil.Process.memory_info()
pmem = namedtuple('pmem', ['rss', 'vms', 'text', 'data', 'stack'])
# psutil.Process.memory_full_info()
pfullmem = pmem
# psutil.Process.cpu_times()
pcputimes = namedtuple('pcputimes',
['user', 'system', 'children_user', 'children_system'])
# psutil.Process.memory_maps(grouped=True)
pmmap_grouped = namedtuple( pmmap_grouped = namedtuple(
'pmmap_grouped', 'path rss, private, ref_count, shadow_count') 'pmmap_grouped', 'path rss, private, ref_count, shadow_count')
# psutil.Process.memory_maps(grouped=False)
pmmap_ext = namedtuple( pmmap_ext = namedtuple(
'pmmap_ext', 'addr, perms path rss, private, ref_count, shadow_count') 'pmmap_ext', 'addr, perms path rss, private, ref_count, shadow_count')
# psutil.disk_io_counters()
if FREEBSD:
sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
'read_bytes', 'write_bytes',
'read_time', 'write_time',
'busy_time'])
else:
sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
'read_bytes', 'write_bytes'])
# set later from __init__.py
NoSuchProcess = None # =====================================================================
ZombieProcess = None # --- memory
AccessDenied = None # =====================================================================
TimeoutExpired = None
def virtual_memory(): def virtual_memory():
"""System virtual memory as a namedtuple.""" """System virtual memory as a namedtuple."""
mem = cext.virtual_mem() mem = cext.virtual_mem()
total, free, active, inactive, wired, cached, buffers, shared = mem total, free, active, inactive, wired, cached, buffers, shared = mem
if NETBSD:
# On NetBSD buffers and shared mem is determined via /proc.
# The C ext set them to 0.
with open('/proc/meminfo', 'rb') as f:
for line in f:
if line.startswith(b'Buffers:'):
buffers = int(line.split()[1]) * 1024
elif line.startswith(b'MemShared:'):
shared = int(line.split()[1]) * 1024
avail = inactive + cached + free avail = inactive + cached + free
used = active + wired + cached used = active + wired + cached
percent = usage_percent((total - avail), total, _round=1) percent = usage_percent((total - avail), total, _round=1)
@ -84,11 +195,16 @@ def virtual_memory():
def swap_memory(): def swap_memory():
"""System swap memory as (total, used, free, sin, sout) namedtuple.""" """System swap memory as (total, used, free, sin, sout) namedtuple."""
total, used, free, sin, sout = [x * PAGESIZE for x in cext.swap_mem()] total, used, free, sin, sout = cext.swap_mem()
percent = usage_percent(used, total, _round=1) percent = usage_percent(used, total, _round=1)
return _common.sswap(total, used, free, percent, sin, sout) return _common.sswap(total, used, free, percent, sin, sout)
# =====================================================================
# --- CPU
# =====================================================================
def cpu_times(): def cpu_times():
"""Return system per-CPU times as a namedtuple""" """Return system per-CPU times as a namedtuple"""
user, nice, system, idle, irq = cext.cpu_times() user, nice, system, idle, irq = cext.cpu_times()
@ -113,6 +229,7 @@ else:
# crash at psutil import time. # crash at psutil import time.
# Next calls will fail with NotImplementedError # Next calls will fail with NotImplementedError
def per_cpu_times(): def per_cpu_times():
"""Return system CPU times as a namedtuple"""
if cpu_count_logical() == 1: if cpu_count_logical() == 1:
return [cpu_times()] return [cpu_times()]
if per_cpu_times.__called__: if per_cpu_times.__called__:
@ -128,73 +245,140 @@ def cpu_count_logical():
return cext.cpu_count_logical() return cext.cpu_count_logical()
def cpu_count_physical(): if OPENBSD or NETBSD:
"""Return the number of physical CPUs in the system.""" def cpu_count_physical():
# From the C module we'll get an XML string similar to this: # OpenBSD and NetBSD do not implement this.
# http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html return 1 if cpu_count_logical() == 1 else None
# We may get None in case "sysctl kern.sched.topology_spec" else:
# is not supported on this BSD version, in which case we'll mimic def cpu_count_physical():
# os.cpu_count() and return None. """Return the number of physical CPUs in the system."""
ret = None # From the C module we'll get an XML string similar to this:
s = cext.cpu_count_phys() # http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html
if s is not None: # We may get None in case "sysctl kern.sched.topology_spec"
# get rid of padding chars appended at the end of the string # is not supported on this BSD version, in which case we'll mimic
index = s.rfind("</groups>") # os.cpu_count() and return None.
if index != -1: ret = None
s = s[:index + 9] s = cext.cpu_count_phys()
root = ET.fromstring(s) if s is not None:
try: # get rid of padding chars appended at the end of the string
ret = len(root.findall('group/children/group/cpu')) or None index = s.rfind("</groups>")
finally: if index != -1:
# needed otherwise it will memleak s = s[:index + 9]
root.clear() root = ET.fromstring(s)
if not ret: try:
# If logical CPUs are 1 it's obvious we'll have only 1 ret = len(root.findall('group/children/group/cpu')) or None
# physical CPU. finally:
if cpu_count_logical() == 1: # needed otherwise it will memleak
return 1 root.clear()
return ret if not ret:
# If logical CPUs are 1 it's obvious we'll have only 1
# physical CPU.
if cpu_count_logical() == 1:
return 1
return ret
def boot_time(): def cpu_stats():
"""The system boot time expressed in seconds since the epoch.""" """Return various CPU stats as a named tuple."""
return cext.boot_time() if FREEBSD:
# Note: the C ext is returning some metrics we are not exposing:
# traps.
ctxsw, intrs, soft_intrs, syscalls, traps = cext.cpu_stats()
elif NETBSD:
# XXX
# Note about intrs: the C extension returns 0. intrs
# can be determined via /proc/stat; it has the same value as
# soft_intrs thought so the kernel is faking it (?).
#
# Note about syscalls: the C extension always sets it to 0 (?).
#
# Note: the C ext is returning some metrics we are not exposing:
# traps, faults and forks.
ctxsw, intrs, soft_intrs, syscalls, traps, faults, forks = \
cext.cpu_stats()
with open('/proc/stat', 'rb') as f:
for line in f:
if line.startswith(b'intr'):
intrs = int(line.split()[1])
elif OPENBSD:
# Note: the C ext is returning some metrics we are not exposing:
# traps, faults and forks.
ctxsw, intrs, soft_intrs, syscalls, traps, faults, forks = \
cext.cpu_stats()
return _common.scpustats(ctxsw, intrs, soft_intrs, syscalls)
# =====================================================================
# --- disks
# =====================================================================
def disk_partitions(all=False): def disk_partitions(all=False):
"""Return mounted disk partitions as a list of namedtuples.
'all' argument is ignored, see:
https://github.com/giampaolo/psutil/issues/906
"""
retlist = [] retlist = []
partitions = cext.disk_partitions() partitions = cext.disk_partitions()
for partition in partitions: for partition in partitions:
device, mountpoint, fstype, opts = partition device, mountpoint, fstype, opts = partition
if device == 'none':
device = ''
if not all:
if not os.path.isabs(device) or not os.path.exists(device):
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts) ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple) retlist.append(ntuple)
return retlist return retlist
def users(): disk_usage = _psposix.disk_usage
retlist = [] disk_io_counters = cext.disk_io_counters
rawlist = cext.users()
for item in rawlist:
user, tty, hostname, tstamp = item # =====================================================================
if tty == '~': # --- network
continue # reboot or shutdown # =====================================================================
nt = _common.suser(user, tty or None, hostname, tstamp)
retlist.append(nt)
return retlist net_io_counters = cext.net_io_counters
net_if_addrs = cext_posix.net_if_addrs
def net_if_stats():
"""Get NIC stats (isup, duplex, speed, mtu)."""
names = net_io_counters().keys()
ret = {}
for name in names:
mtu = cext_posix.net_if_mtu(name)
isup = cext_posix.net_if_flags(name)
duplex, speed = cext_posix.net_if_duplex_speed(name)
if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex)
ret[name] = _common.snicstats(isup, duplex, speed, mtu)
return ret
def net_connections(kind): def net_connections(kind):
"""System-wide network connections."""
if OPENBSD:
ret = []
for pid in pids():
try:
cons = Process(pid).connections(kind)
except (NoSuchProcess, ZombieProcess):
continue
else:
for conn in cons:
conn = list(conn)
conn.append(pid)
ret.append(_common.sconn(*conn))
return ret
if kind not in _common.conn_tmap: if kind not in _common.conn_tmap:
raise ValueError("invalid %r kind argument; choose between %s" raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in conn_tmap]))) % (kind, ', '.join([repr(x) for x in conn_tmap])))
families, types = conn_tmap[kind] families, types = conn_tmap[kind]
ret = set() ret = set()
rawlist = cext.net_connections() if NETBSD:
rawlist = cext.net_connections(-1)
else:
rawlist = cext.net_connections()
for item in rawlist: for item in rawlist:
fd, fam, type, laddr, raddr, status, pid = item fd, fam, type, laddr, raddr, status, pid = item
# TODO: apply filter at C level # TODO: apply filter at C level
@ -207,6 +391,11 @@ def net_connections(kind):
# have a very short lifetime so maybe the kernel # have a very short lifetime so maybe the kernel
# can't initialize their status? # can't initialize their status?
status = TCP_STATUSES[cext.PSUTIL_CONN_NONE] status = TCP_STATUSES[cext.PSUTIL_CONN_NONE]
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
fam = sockfam_to_enum(fam) fam = sockfam_to_enum(fam)
type = socktype_to_enum(type) type = socktype_to_enum(type)
nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid) nt = _common.sconn(fd, fam, type, laddr, raddr, status, pid)
@ -214,24 +403,95 @@ def net_connections(kind):
return list(ret) return list(ret)
def net_if_stats(): # =====================================================================
"""Get NIC stats (isup, duplex, speed, mtu).""" # --- sensors
names = net_io_counters().keys() # =====================================================================
ret = {}
for name in names:
isup, duplex, speed, mtu = cext_posix.net_if_stats(name) if FREEBSD:
if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex) def sensors_battery():
ret[name] = _common.snicstats(isup, duplex, speed, mtu) """Return battery info."""
try:
percent, minsleft, power_plugged = cext.sensors_battery()
except NotImplementedError:
# See: https://github.com/giampaolo/psutil/issues/1074
return None
power_plugged = power_plugged == 1
if power_plugged:
secsleft = _common.POWER_TIME_UNLIMITED
elif minsleft == -1:
secsleft = _common.POWER_TIME_UNKNOWN
else:
secsleft = minsleft * 60
return _common.sbattery(percent, secsleft, power_plugged)
# =====================================================================
# --- other system functions
# =====================================================================
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
return cext.boot_time()
def users():
"""Return currently connected users as a list of namedtuples."""
retlist = []
rawlist = cext.users()
for item in rawlist:
user, tty, hostname, tstamp, pid = item
if pid == -1:
assert OPENBSD
pid = None
if tty == '~':
continue # reboot or shutdown
nt = _common.suser(user, tty or None, hostname, tstamp, pid)
retlist.append(nt)
return retlist
# =====================================================================
# --- processes
# =====================================================================
@memoize
def _pid_0_exists():
try:
Process(0).name()
except NoSuchProcess:
return False
except AccessDenied:
return True
else:
return True
def pids():
"""Returns a list of PIDs currently running on the system."""
ret = cext.pids()
if OPENBSD and (0 not in ret) and _pid_0_exists():
# On OpenBSD the kernel does not return PID 0 (neither does
# ps) but it's actually querable (Process(0) will succeed).
ret.insert(0, 0)
return ret return ret
pids = cext.pids if OPENBSD or NETBSD:
pid_exists = _psposix.pid_exists def pid_exists(pid):
disk_usage = _psposix.disk_usage """Return True if pid exists."""
net_io_counters = cext.net_io_counters exists = _psposix.pid_exists(pid)
disk_io_counters = cext.disk_io_counters if not exists:
net_if_addrs = cext_posix.net_if_addrs # We do this because _psposix.pid_exists() lies in case of
# zombie processes.
return pid in pids()
else:
return True
else:
pid_exists = _psposix.pid_exists
def wrap_exceptions(fun): def wrap_exceptions(fun):
@ -243,10 +503,11 @@ def wrap_exceptions(fun):
try: try:
return fun(self, *args, **kwargs) return fun(self, *args, **kwargs)
except OSError as err: except OSError as err:
# support for private module import if self.pid == 0:
if (NoSuchProcess is None or AccessDenied is None or if 0 in pids():
ZombieProcess is None): raise AccessDenied(self.pid, self._name)
raise else:
raise
if err.errno == errno.ESRCH: if err.errno == errno.ESRCH:
if not pid_exists(self.pid): if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name) raise NoSuchProcess(self.pid, self._name)
@ -258,6 +519,25 @@ def wrap_exceptions(fun):
return wrapper return wrapper
@contextlib.contextmanager
def wrap_exceptions_procfs(inst):
"""Same as above, for routines relying on reading /proc fs."""
try:
yield
except EnvironmentError as 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):
if not pid_exists(inst.pid):
raise NoSuchProcess(inst.pid, inst._name)
else:
raise ZombieProcess(inst.pid, inst._name, inst._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(inst.pid, inst._name)
raise
class Process(object): class Process(object):
"""Wrapper class around underlying C implementation.""" """Wrapper class around underlying C implementation."""
@ -268,22 +548,72 @@ class Process(object):
self._name = None self._name = None
self._ppid = None self._ppid = None
@memoize_when_activated
def oneshot(self):
"""Retrieves multiple process info in one shot as a raw tuple."""
ret = cext.proc_oneshot_info(self.pid)
assert len(ret) == len(kinfo_proc_map)
return ret
def oneshot_enter(self):
self.oneshot.cache_activate()
def oneshot_exit(self):
self.oneshot.cache_deactivate()
@wrap_exceptions @wrap_exceptions
def name(self): def name(self):
return cext.proc_name(self.pid) name = self.oneshot()[kinfo_proc_map['name']]
return name if name is not None else cext.proc_name(self.pid)
@wrap_exceptions @wrap_exceptions
def exe(self): def exe(self):
return cext.proc_exe(self.pid) if FREEBSD:
return cext.proc_exe(self.pid)
elif NETBSD:
if self.pid == 0:
# /proc/0 dir exists but /proc/0/exe doesn't
return ""
with wrap_exceptions_procfs(self):
return os.readlink("/proc/%s/exe" % self.pid)
else:
# OpenBSD: exe cannot be determined; references:
# https://chromium.googlesource.com/chromium/src/base/+/
# master/base_paths_posix.cc
# We try our best guess by using which against the first
# cmdline arg (may return None).
cmdline = self.cmdline()
if cmdline:
return which(cmdline[0])
else:
return ""
@wrap_exceptions @wrap_exceptions
def cmdline(self): def cmdline(self):
return cext.proc_cmdline(self.pid) if OPENBSD and self.pid == 0:
return [] # ...else it crashes
elif NETBSD:
# XXX - most of the times the underlying sysctl() call on Net
# and Open BSD returns a truncated string.
# Also /proc/pid/cmdline behaves the same so it looks
# like this is a kernel bug.
try:
return cext.proc_cmdline(self.pid)
except OSError as err:
if err.errno == errno.EINVAL:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
else:
raise
else:
return cext.proc_cmdline(self.pid)
@wrap_exceptions @wrap_exceptions
def terminal(self): def terminal(self):
tty_nr = cext.proc_tty_nr(self.pid) tty_nr = self.oneshot()[kinfo_proc_map['ttynr']]
tmap = _psposix._get_terminal_map() tmap = _psposix.get_terminal_map()
try: try:
return tmap[tty_nr] return tmap[tty_nr]
except KeyError: except KeyError:
@ -291,51 +621,83 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def ppid(self): def ppid(self):
return cext.proc_ppid(self.pid) self._ppid = self.oneshot()[kinfo_proc_map['ppid']]
return self._ppid
@wrap_exceptions @wrap_exceptions
def uids(self): def uids(self):
real, effective, saved = cext.proc_uids(self.pid) rawtuple = self.oneshot()
return _common.puids(real, effective, saved) return _common.puids(
rawtuple[kinfo_proc_map['real_uid']],
rawtuple[kinfo_proc_map['effective_uid']],
rawtuple[kinfo_proc_map['saved_uid']])
@wrap_exceptions @wrap_exceptions
def gids(self): def gids(self):
real, effective, saved = cext.proc_gids(self.pid) rawtuple = self.oneshot()
return _common.pgids(real, effective, saved) return _common.pgids(
rawtuple[kinfo_proc_map['real_gid']],
rawtuple[kinfo_proc_map['effective_gid']],
rawtuple[kinfo_proc_map['saved_gid']])
@wrap_exceptions @wrap_exceptions
def cpu_times(self): def cpu_times(self):
user, system = cext.proc_cpu_times(self.pid) rawtuple = self.oneshot()
return _common.pcputimes(user, system) return _common.pcputimes(
rawtuple[kinfo_proc_map['user_time']],
rawtuple[kinfo_proc_map['sys_time']],
rawtuple[kinfo_proc_map['ch_user_time']],
rawtuple[kinfo_proc_map['ch_sys_time']])
if FREEBSD:
@wrap_exceptions
def cpu_num(self):
return self.oneshot()[kinfo_proc_map['cpunum']]
@wrap_exceptions @wrap_exceptions
def memory_info(self): def memory_info(self):
rss, vms = cext.proc_memory_info(self.pid)[:2] rawtuple = self.oneshot()
return _common.pmem(rss, vms) return pmem(
rawtuple[kinfo_proc_map['rss']],
rawtuple[kinfo_proc_map['vms']],
rawtuple[kinfo_proc_map['memtext']],
rawtuple[kinfo_proc_map['memdata']],
rawtuple[kinfo_proc_map['memstack']])
@wrap_exceptions memory_full_info = memory_info
def memory_info_ex(self):
return pextmem(*cext.proc_memory_info(self.pid))
@wrap_exceptions @wrap_exceptions
def create_time(self): def create_time(self):
return cext.proc_create_time(self.pid) return self.oneshot()[kinfo_proc_map['create_time']]
@wrap_exceptions @wrap_exceptions
def num_threads(self): def num_threads(self):
return cext.proc_num_threads(self.pid) if hasattr(cext, "proc_num_threads"):
# FreeBSD
return cext.proc_num_threads(self.pid)
else:
return len(self.threads())
@wrap_exceptions @wrap_exceptions
def num_ctx_switches(self): def num_ctx_switches(self):
return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid)) rawtuple = self.oneshot()
return _common.pctxsw(
rawtuple[kinfo_proc_map['ctx_switches_vol']],
rawtuple[kinfo_proc_map['ctx_switches_unvol']])
@wrap_exceptions @wrap_exceptions
def threads(self): def threads(self):
# Note: on OpenSBD this (/dev/mem) requires root access.
rawlist = cext.proc_threads(self.pid) rawlist = cext.proc_threads(self.pid)
retlist = [] retlist = []
for thread_id, utime, stime in rawlist: for thread_id, utime, stime in rawlist:
ntuple = _common.pthread(thread_id, utime, stime) ntuple = _common.pthread(thread_id, utime, stime)
retlist.append(ntuple) retlist.append(ntuple)
if OPENBSD:
# On OpenBSD the underlying C function does not raise NSP
# in case the process is gone (and the returned list may
# incomplete).
self.name() # raise NSP if the process disappeared on us
return retlist return retlist
@wrap_exceptions @wrap_exceptions
@ -343,27 +705,59 @@ class Process(object):
if kind not in conn_tmap: if kind not in conn_tmap:
raise ValueError("invalid %r kind argument; choose between %s" raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in conn_tmap]))) % (kind, ', '.join([repr(x) for x in conn_tmap])))
if NETBSD:
families, types = conn_tmap[kind]
ret = set()
rawlist = cext.net_connections(self.pid)
for item in rawlist:
fd, fam, type, laddr, raddr, status, pid = item
assert pid == self.pid
if fam in families and type in types:
try:
status = TCP_STATUSES[status]
except KeyError:
status = TCP_STATUSES[cext.PSUTIL_CONN_NONE]
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
fam = sockfam_to_enum(fam)
type = socktype_to_enum(type)
nt = _common.pconn(fd, fam, type, laddr, raddr, status)
ret.add(nt)
# On NetBSD the underlying C function does not raise NSP
# in case the process is gone (and the returned list may
# incomplete).
self.name() # raise NSP if the process disappeared on us
return list(ret)
families, types = conn_tmap[kind] families, types = conn_tmap[kind]
rawlist = cext.proc_connections(self.pid, families, types) rawlist = cext.proc_connections(self.pid, families, types)
ret = [] ret = []
for item in rawlist: for item in rawlist:
fd, fam, type, laddr, raddr, status = item fd, fam, type, laddr, raddr, status = item
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
fam = sockfam_to_enum(fam) fam = sockfam_to_enum(fam)
type = socktype_to_enum(type) type = socktype_to_enum(type)
status = TCP_STATUSES[status] status = TCP_STATUSES[status]
nt = _common.pconn(fd, fam, type, laddr, raddr, status) nt = _common.pconn(fd, fam, type, laddr, raddr, status)
ret.append(nt) ret.append(nt)
if OPENBSD:
# On OpenBSD the underlying C function does not raise NSP
# in case the process is gone (and the returned list may
# incomplete).
self.name() # raise NSP if the process disappeared on us
return ret return ret
@wrap_exceptions @wrap_exceptions
def wait(self, timeout=None): def wait(self, timeout=None):
try: return _psposix.wait_pid(self.pid, timeout, self._name)
return _psposix.wait_pid(self.pid, timeout)
except _psposix.TimeoutExpired:
# support for private module import
if TimeoutExpired is None:
raise
raise TimeoutExpired(timeout, self.pid, self._name)
@wrap_exceptions @wrap_exceptions
def nice_get(self): def nice_get(self):
@ -375,81 +769,105 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def status(self): def status(self):
code = cext.proc_status(self.pid) code = self.oneshot()[kinfo_proc_map['status']]
if code in PROC_STATUSES: # XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES[code] return PROC_STATUSES.get(code, '?')
# XXX is this legit? will we even ever get here?
return "?"
@wrap_exceptions @wrap_exceptions
def io_counters(self): def io_counters(self):
rc, wc, rb, wb = cext.proc_io_counters(self.pid) rawtuple = self.oneshot()
return _common.pio(rc, wc, rb, wb) return _common.pio(
rawtuple[kinfo_proc_map['read_io_count']],
rawtuple[kinfo_proc_map['write_io_count']],
-1,
-1)
@wrap_exceptions
def cwd(self):
"""Return process current working directory."""
# sometimes we get an empty string, in which case we turn
# it into None
if OPENBSD and self.pid == 0:
return None # ...else it would raise EINVAL
elif NETBSD:
with wrap_exceptions_procfs(self):
return os.readlink("/proc/%s/cwd" % self.pid)
elif hasattr(cext, 'proc_open_files'):
# FreeBSD < 8 does not support functions based on
# kinfo_getfile() and kinfo_getvmmap()
return cext.proc_cwd(self.pid) or None
else:
raise NotImplementedError(
"supported only starting from FreeBSD 8" if
FREEBSD else "")
nt_mmap_grouped = namedtuple( nt_mmap_grouped = namedtuple(
'mmap', 'path rss, private, ref_count, shadow_count') 'mmap', 'path rss, private, ref_count, shadow_count')
nt_mmap_ext = namedtuple( nt_mmap_ext = namedtuple(
'mmap', 'addr, perms path rss, private, ref_count, shadow_count') 'mmap', 'addr, perms path rss, private, ref_count, shadow_count')
def _not_implemented(self):
raise NotImplementedError
# FreeBSD < 8 does not support functions based on kinfo_getfile() # FreeBSD < 8 does not support functions based on kinfo_getfile()
# and kinfo_getvmmap() # and kinfo_getvmmap()
if hasattr(cext, 'proc_open_files'): if hasattr(cext, 'proc_open_files'):
@wrap_exceptions @wrap_exceptions
def open_files(self): def open_files(self):
"""Return files opened by process as a list of namedtuples.""" """Return files opened by process as a list of namedtuples."""
rawlist = cext.proc_open_files(self.pid) rawlist = cext.proc_open_files(self.pid)
return [_common.popenfile(path, fd) for path, fd in rawlist] return [_common.popenfile(path, fd) for path, fd in rawlist]
else:
open_files = _not_implemented
# FreeBSD < 8 does not support functions based on kinfo_getfile()
# and kinfo_getvmmap()
if hasattr(cext, 'proc_num_fds'):
@wrap_exceptions
def num_fds(self):
"""Return the number of file descriptors opened by this process."""
ret = cext.proc_num_fds(self.pid)
if NETBSD:
# On NetBSD the underlying C function does not raise NSP
# in case the process is gone.
self.name() # raise NSP if the process disappeared on us
return ret
else:
num_fds = _not_implemented
# --- FreeBSD only APIs
if FREEBSD:
@wrap_exceptions @wrap_exceptions
def cwd(self): def cpu_affinity_get(self):
"""Return process current working directory.""" return cext.proc_cpu_affinity_get(self.pid)
# sometimes we get an empty string, in which case we turn
# it into None @wrap_exceptions
return cext.proc_cwd(self.pid) or None def cpu_affinity_set(self, cpus):
# Pre-emptively check if CPUs are valid because the C
# function has a weird behavior in case of invalid CPUs,
# see: https://github.com/giampaolo/psutil/issues/586
allcpus = tuple(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in allcpus:
raise ValueError("invalid CPU #%i (choose between %s)"
% (cpu, allcpus))
try:
cext.proc_cpu_affinity_set(self.pid, cpus)
except OSError as err:
# 'man cpuset_setaffinity' about EDEADLK:
# <<the call would leave a thread without a valid CPU to run
# on because the set does not overlap with the thread's
# anonymous mask>>
if err.errno in (errno.EINVAL, errno.EDEADLK):
for cpu in cpus:
if cpu not in allcpus:
raise ValueError(
"invalid CPU #%i (choose between %s)" % (
cpu, allcpus))
raise
@wrap_exceptions @wrap_exceptions
def memory_maps(self): def memory_maps(self):
return cext.proc_memory_maps(self.pid) return cext.proc_memory_maps(self.pid)
@wrap_exceptions
def num_fds(self):
"""Return the number of file descriptors opened by this process."""
return cext.proc_num_fds(self.pid)
else:
def _not_implemented(self):
raise NotImplementedError("supported only starting from FreeBSD 8")
open_files = _not_implemented
proc_cwd = _not_implemented
memory_maps = _not_implemented
num_fds = _not_implemented
@wrap_exceptions
def cpu_affinity_get(self):
return cext.proc_cpu_affinity_get(self.pid)
@wrap_exceptions
def cpu_affinity_set(self, cpus):
# Pre-emptively check if CPUs are valid because the C
# function has a weird behavior in case of invalid CPUs,
# see: https://github.com/giampaolo/psutil/issues/586
allcpus = tuple(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in allcpus:
raise ValueError("invalid CPU #%i (choose between %s)"
% (cpu, allcpus))
try:
cext.proc_cpu_affinity_set(self.pid, cpus)
except OSError as err:
# 'man cpuset_setaffinity' about EDEADLK:
# <<the call would leave a thread without a valid CPU to run
# on because the set does not overlap with the thread's
# anonymous mask>>
if err.errno in (errno.EINVAL, errno.EDEADLK):
for cpu in cpus:
if cpu not in allcpus:
raise ValueError("invalid CPU #%i (choose between %s)"
% (cpu, allcpus))
raise

1643
third_party/python/psutil/psutil/_pslinux.py поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

376
third_party/python/psutil/psutil/_psosx.py поставляемый
Просмотреть файл

@ -1,32 +1,44 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
"""OSX platform implementation.""" """OSX platform implementation."""
import contextlib
import errno import errno
import functools import functools
import os import os
from socket import AF_INET
from collections import namedtuple from collections import namedtuple
from . import _common from . import _common
from . import _psposix from . import _psposix
from . import _psutil_osx as cext from . import _psutil_osx as cext
from . import _psutil_posix as cext_posix from . import _psutil_posix as cext_posix
from ._common import conn_tmap, usage_percent, isfile_strict from ._common import AF_INET6
from ._common import sockfam_to_enum, socktype_to_enum from ._common import conn_tmap
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._exceptions import AccessDenied
from ._exceptions import NoSuchProcess
from ._exceptions import ZombieProcess
__extra__all__ = [] __extra__all__ = []
# --- constants
# =====================================================================
# --- globals
# =====================================================================
PAGESIZE = os.sysconf("SC_PAGE_SIZE") PAGESIZE = os.sysconf("SC_PAGE_SIZE")
AF_LINK = cext_posix.AF_LINK AF_LINK = cext_posix.AF_LINK
# http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
TCP_STATUSES = { TCP_STATUSES = {
cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED, cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT, cext.TCPS_SYN_SENT: _common.CONN_SYN_SENT,
@ -50,29 +62,60 @@ PROC_STATUSES = {
cext.SZOMB: _common.STATUS_ZOMBIE, cext.SZOMB: _common.STATUS_ZOMBIE,
} }
scputimes = namedtuple('scputimes', ['user', 'nice', 'system', 'idle']) kinfo_proc_map = dict(
ppid=0,
ruid=1,
euid=2,
suid=3,
rgid=4,
egid=5,
sgid=6,
ttynr=7,
ctime=8,
status=9,
name=10,
)
pidtaskinfo_map = dict(
cpuutime=0,
cpustime=1,
rss=2,
vms=3,
pfaults=4,
pageins=5,
numthreads=6,
volctxsw=7,
)
# =====================================================================
# --- named tuples
# =====================================================================
# psutil.cpu_times()
scputimes = namedtuple('scputimes', ['user', 'nice', 'system', 'idle'])
# psutil.virtual_memory()
svmem = namedtuple( svmem = namedtuple(
'svmem', ['total', 'available', 'percent', 'used', 'free', 'svmem', ['total', 'available', 'percent', 'used', 'free',
'active', 'inactive', 'wired']) 'active', 'inactive', 'wired'])
# psutil.Process.memory_info()
pextmem = namedtuple('pextmem', ['rss', 'vms', 'pfaults', 'pageins']) pmem = namedtuple('pmem', ['rss', 'vms', 'pfaults', 'pageins'])
# psutil.Process.memory_full_info()
pfullmem = namedtuple('pfullmem', pmem._fields + ('uss', ))
# psutil.Process.memory_maps(grouped=True)
pmmap_grouped = namedtuple( pmmap_grouped = namedtuple(
'pmmap_grouped', 'pmmap_grouped',
'path rss private swapped dirtied ref_count shadow_depth') 'path rss private swapped dirtied ref_count shadow_depth')
# psutil.Process.memory_maps(grouped=False)
pmmap_ext = namedtuple( pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields)) 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
# set later from __init__.py
NoSuchProcess = None
ZombieProcess = None
AccessDenied = None
TimeoutExpired = None
# =====================================================================
# --- memory
# =====================================================================
# --- functions
def virtual_memory(): def virtual_memory():
"""System virtual memory as a namedtuple.""" """System virtual memory as a namedtuple."""
@ -91,6 +134,11 @@ def swap_memory():
return _common.sswap(total, used, free, percent, sin, sout) return _common.sswap(total, used, free, percent, sin, sout)
# =====================================================================
# --- CPU
# =====================================================================
def cpu_times(): def cpu_times():
"""Return system CPU times as a namedtuple.""" """Return system CPU times as a namedtuple."""
user, nice, system, idle = cext.cpu_times() user, nice, system, idle = cext.cpu_times()
@ -117,12 +165,34 @@ def cpu_count_physical():
return cext.cpu_count_phys() return cext.cpu_count_phys()
def boot_time(): def cpu_stats():
"""The system boot time expressed in seconds since the epoch.""" ctx_switches, interrupts, soft_interrupts, syscalls, traps = \
return cext.boot_time() cext.cpu_stats()
return _common.scpustats(
ctx_switches, interrupts, soft_interrupts, syscalls)
def cpu_freq():
"""Return CPU frequency.
On OSX per-cpu frequency is not supported.
Also, the returned frequency never changes, see:
https://arstechnica.com/civis/viewtopic.php?f=19&t=465002
"""
curr, min_, max_ = cext.cpu_freq()
return [_common.scpufreq(curr, min_, max_)]
# =====================================================================
# --- disks
# =====================================================================
disk_usage = _psposix.disk_usage
disk_io_counters = cext.disk_io_counters
def disk_partitions(all=False): def disk_partitions(all=False):
"""Return mounted disk partitions as a list of namedtuples."""
retlist = [] retlist = []
partitions = cext.disk_partitions() partitions = cext.disk_partitions()
for partition in partitions: for partition in partitions:
@ -137,21 +207,40 @@ def disk_partitions(all=False):
return retlist return retlist
def users(): # =====================================================================
retlist = [] # --- sensors
rawlist = cext.users() # =====================================================================
for item in rawlist:
user, tty, hostname, tstamp = item
if tty == '~': def sensors_battery():
continue # reboot or shutdown """Return battery information.
if not tstamp: """
continue try:
nt = _common.suser(user, tty or None, hostname or None, tstamp) percent, minsleft, power_plugged = cext.sensors_battery()
retlist.append(nt) except NotImplementedError:
return retlist # no power source - return None according to interface
return None
power_plugged = power_plugged == 1
if power_plugged:
secsleft = _common.POWER_TIME_UNLIMITED
elif minsleft == -1:
secsleft = _common.POWER_TIME_UNKNOWN
else:
secsleft = minsleft * 60
return _common.sbattery(percent, secsleft, power_plugged)
# =====================================================================
# --- network
# =====================================================================
net_io_counters = cext.net_io_counters
net_if_addrs = cext_posix.net_if_addrs
def net_connections(kind='inet'): def net_connections(kind='inet'):
"""System-wide network connections."""
# Note: on OSX this will fail with AccessDenied unless # Note: on OSX this will fail with AccessDenied unless
# the process is owned by root. # the process is owned by root.
ret = [] ret = []
@ -173,19 +262,62 @@ def net_if_stats():
names = net_io_counters().keys() names = net_io_counters().keys()
ret = {} ret = {}
for name in names: for name in names:
isup, duplex, speed, mtu = cext_posix.net_if_stats(name) mtu = cext_posix.net_if_mtu(name)
isup = cext_posix.net_if_flags(name)
duplex, speed = cext_posix.net_if_duplex_speed(name)
if hasattr(_common, 'NicDuplex'): if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex) duplex = _common.NicDuplex(duplex)
ret[name] = _common.snicstats(isup, duplex, speed, mtu) ret[name] = _common.snicstats(isup, duplex, speed, mtu)
return ret return ret
pids = cext.pids # =====================================================================
# --- other system functions
# =====================================================================
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
return cext.boot_time()
def users():
"""Return currently connected users as a list of namedtuples."""
retlist = []
rawlist = cext.users()
for item in rawlist:
user, tty, hostname, tstamp, pid = item
if tty == '~':
continue # reboot or shutdown
if not tstamp:
continue
nt = _common.suser(user, tty or None, hostname or None, tstamp, pid)
retlist.append(nt)
return retlist
# =====================================================================
# --- processes
# =====================================================================
def pids():
ls = cext.pids()
if 0 not in ls:
# On certain OSX versions pids() C doesn't return PID 0 but
# "ps" does and the process is querable via sysctl():
# https://travis-ci.org/giampaolo/psutil/jobs/309619941
try:
Process(0).create_time()
ls.append(0)
except NoSuchProcess:
pass
except AccessDenied:
ls.append(0)
return ls
pid_exists = _psposix.pid_exists pid_exists = _psposix.pid_exists
disk_usage = _psposix.disk_usage
net_io_counters = cext.net_io_counters
disk_io_counters = cext.disk_io_counters
net_if_addrs = cext_posix.net_if_addrs
def wrap_exceptions(fun): def wrap_exceptions(fun):
@ -197,21 +329,40 @@ def wrap_exceptions(fun):
try: try:
return fun(self, *args, **kwargs) return fun(self, *args, **kwargs)
except OSError as err: except OSError as err:
# support for private module import
if (NoSuchProcess is None or AccessDenied is None or
ZombieProcess is None):
raise
if err.errno == errno.ESRCH: if err.errno == errno.ESRCH:
if not pid_exists(self.pid): raise NoSuchProcess(self.pid, self._name)
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES): if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name) raise AccessDenied(self.pid, self._name)
raise raise
return wrapper return wrapper
@contextlib.contextmanager
def catch_zombie(proc):
"""There are some poor C APIs which incorrectly raise ESRCH when
the process is still alive or it's a zombie, or even RuntimeError
(those who don't set errno). This is here in order to solve:
https://github.com/giampaolo/psutil/issues/1044
"""
try:
yield
except (OSError, RuntimeError) as err:
if isinstance(err, RuntimeError) or err.errno == errno.ESRCH:
try:
# status() is not supposed to lie and correctly detect
# zombies so if it raises ESRCH it's true.
status = proc.status()
except NoSuchProcess:
raise err
else:
if status == _common.STATUS_ZOMBIE:
raise ZombieProcess(proc.pid, proc._name, proc._ppid)
else:
raise AccessDenied(proc.pid, proc._name)
else:
raise
class Process(object): class Process(object):
"""Wrapper class around underlying C implementation.""" """Wrapper class around underlying C implementation."""
@ -222,42 +373,79 @@ class Process(object):
self._name = None self._name = None
self._ppid = None self._ppid = None
@memoize_when_activated
def _get_kinfo_proc(self):
# Note: should work with all PIDs without permission issues.
ret = cext.proc_kinfo_oneshot(self.pid)
assert len(ret) == len(kinfo_proc_map)
return ret
@memoize_when_activated
def _get_pidtaskinfo(self):
# Note: should work for PIDs owned by user only.
with catch_zombie(self):
ret = cext.proc_pidtaskinfo_oneshot(self.pid)
assert len(ret) == len(pidtaskinfo_map)
return ret
def oneshot_enter(self):
self._get_kinfo_proc.cache_activate()
self._get_pidtaskinfo.cache_activate()
def oneshot_exit(self):
self._get_kinfo_proc.cache_deactivate()
self._get_pidtaskinfo.cache_deactivate()
@wrap_exceptions @wrap_exceptions
def name(self): def name(self):
return cext.proc_name(self.pid) name = self._get_kinfo_proc()[kinfo_proc_map['name']]
return name if name is not None else cext.proc_name(self.pid)
@wrap_exceptions @wrap_exceptions
def exe(self): def exe(self):
return cext.proc_exe(self.pid) with catch_zombie(self):
return cext.proc_exe(self.pid)
@wrap_exceptions @wrap_exceptions
def cmdline(self): def cmdline(self):
if not pid_exists(self.pid): with catch_zombie(self):
raise NoSuchProcess(self.pid, self._name) return cext.proc_cmdline(self.pid)
return cext.proc_cmdline(self.pid)
@wrap_exceptions
def environ(self):
with catch_zombie(self):
return parse_environ_block(cext.proc_environ(self.pid))
@wrap_exceptions @wrap_exceptions
def ppid(self): def ppid(self):
return cext.proc_ppid(self.pid) self._ppid = self._get_kinfo_proc()[kinfo_proc_map['ppid']]
return self._ppid
@wrap_exceptions @wrap_exceptions
def cwd(self): def cwd(self):
return cext.proc_cwd(self.pid) with catch_zombie(self):
return cext.proc_cwd(self.pid)
@wrap_exceptions @wrap_exceptions
def uids(self): def uids(self):
real, effective, saved = cext.proc_uids(self.pid) rawtuple = self._get_kinfo_proc()
return _common.puids(real, effective, saved) return _common.puids(
rawtuple[kinfo_proc_map['ruid']],
rawtuple[kinfo_proc_map['euid']],
rawtuple[kinfo_proc_map['suid']])
@wrap_exceptions @wrap_exceptions
def gids(self): def gids(self):
real, effective, saved = cext.proc_gids(self.pid) rawtuple = self._get_kinfo_proc()
return _common.pgids(real, effective, saved) return _common.puids(
rawtuple[kinfo_proc_map['rgid']],
rawtuple[kinfo_proc_map['egid']],
rawtuple[kinfo_proc_map['sgid']])
@wrap_exceptions @wrap_exceptions
def terminal(self): def terminal(self):
tty_nr = cext.proc_tty_nr(self.pid) tty_nr = self._get_kinfo_proc()[kinfo_proc_map['ttynr']]
tmap = _psposix._get_terminal_map() tmap = _psposix.get_terminal_map()
try: try:
return tmap[tty_nr] return tmap[tty_nr]
except KeyError: except KeyError:
@ -265,37 +453,52 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def memory_info(self): def memory_info(self):
rss, vms = cext.proc_memory_info(self.pid)[:2] rawtuple = self._get_pidtaskinfo()
return _common.pmem(rss, vms) return pmem(
rawtuple[pidtaskinfo_map['rss']],
rawtuple[pidtaskinfo_map['vms']],
rawtuple[pidtaskinfo_map['pfaults']],
rawtuple[pidtaskinfo_map['pageins']],
)
@wrap_exceptions @wrap_exceptions
def memory_info_ex(self): def memory_full_info(self):
rss, vms, pfaults, pageins = cext.proc_memory_info(self.pid) basic_mem = self.memory_info()
return pextmem(rss, vms, pfaults * PAGESIZE, pageins * PAGESIZE) uss = cext.proc_memory_uss(self.pid)
return pfullmem(*basic_mem + (uss, ))
@wrap_exceptions @wrap_exceptions
def cpu_times(self): def cpu_times(self):
user, system = cext.proc_cpu_times(self.pid) rawtuple = self._get_pidtaskinfo()
return _common.pcputimes(user, system) return _common.pcputimes(
rawtuple[pidtaskinfo_map['cpuutime']],
rawtuple[pidtaskinfo_map['cpustime']],
# children user / system times are not retrievable (set to 0)
0.0, 0.0)
@wrap_exceptions @wrap_exceptions
def create_time(self): def create_time(self):
return cext.proc_create_time(self.pid) return self._get_kinfo_proc()[kinfo_proc_map['ctime']]
@wrap_exceptions @wrap_exceptions
def num_ctx_switches(self): def num_ctx_switches(self):
return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid)) # Unvoluntary value seems not to be available;
# getrusage() numbers seems to confirm this theory.
# We set it to 0.
vol = self._get_pidtaskinfo()[pidtaskinfo_map['volctxsw']]
return _common.pctxsw(vol, 0)
@wrap_exceptions @wrap_exceptions
def num_threads(self): def num_threads(self):
return cext.proc_num_threads(self.pid) return self._get_pidtaskinfo()[pidtaskinfo_map['numthreads']]
@wrap_exceptions @wrap_exceptions
def open_files(self): def open_files(self):
if self.pid == 0: if self.pid == 0:
return [] return []
files = [] files = []
rawlist = cext.proc_open_files(self.pid) with catch_zombie(self):
rawlist = cext.proc_open_files(self.pid)
for path, fd in rawlist: for path, fd in rawlist:
if isfile_strict(path): if isfile_strict(path):
ntuple = _common.popenfile(path, fd) ntuple = _common.popenfile(path, fd)
@ -308,13 +511,19 @@ class Process(object):
raise ValueError("invalid %r kind argument; choose between %s" raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in conn_tmap]))) % (kind, ', '.join([repr(x) for x in conn_tmap])))
families, types = conn_tmap[kind] families, types = conn_tmap[kind]
rawlist = cext.proc_connections(self.pid, families, types) with catch_zombie(self):
rawlist = cext.proc_connections(self.pid, families, types)
ret = [] ret = []
for item in rawlist: for item in rawlist:
fd, fam, type, laddr, raddr, status = item fd, fam, type, laddr, raddr, status = item
status = TCP_STATUSES[status] status = TCP_STATUSES[status]
fam = sockfam_to_enum(fam) fam = sockfam_to_enum(fam)
type = socktype_to_enum(type) type = socktype_to_enum(type)
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
nt = _common.pconn(fd, fam, type, laddr, raddr, status) nt = _common.pconn(fd, fam, type, laddr, raddr, status)
ret.append(nt) ret.append(nt)
return ret return ret
@ -323,35 +532,33 @@ class Process(object):
def num_fds(self): def num_fds(self):
if self.pid == 0: if self.pid == 0:
return 0 return 0
return cext.proc_num_fds(self.pid) with catch_zombie(self):
return cext.proc_num_fds(self.pid)
@wrap_exceptions @wrap_exceptions
def wait(self, timeout=None): def wait(self, timeout=None):
try: return _psposix.wait_pid(self.pid, timeout, self._name)
return _psposix.wait_pid(self.pid, timeout)
except _psposix.TimeoutExpired:
# support for private module import
if TimeoutExpired is None:
raise
raise TimeoutExpired(timeout, self.pid, self._name)
@wrap_exceptions @wrap_exceptions
def nice_get(self): def nice_get(self):
return cext_posix.getpriority(self.pid) with catch_zombie(self):
return cext_posix.getpriority(self.pid)
@wrap_exceptions @wrap_exceptions
def nice_set(self, value): def nice_set(self, value):
return cext_posix.setpriority(self.pid, value) with catch_zombie(self):
return cext_posix.setpriority(self.pid, value)
@wrap_exceptions @wrap_exceptions
def status(self): def status(self):
code = cext.proc_status(self.pid) code = self._get_kinfo_proc()[kinfo_proc_map['status']]
# XXX is '?' legit? (we're not supposed to return it anyway) # XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES.get(code, '?') return PROC_STATUSES.get(code, '?')
@wrap_exceptions @wrap_exceptions
def threads(self): def threads(self):
rawlist = cext.proc_threads(self.pid) with catch_zombie(self):
rawlist = cext.proc_threads(self.pid)
retlist = [] retlist = []
for thread_id, utime, stime in rawlist: for thread_id, utime, stime in rawlist:
ntuple = _common.pthread(thread_id, utime, stime) ntuple = _common.pthread(thread_id, utime, stime)
@ -360,4 +567,5 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def memory_maps(self): def memory_maps(self):
return cext.proc_memory_maps(self.pid) with catch_zombie(self):
return cext.proc_memory_maps(self.pid)

88
third_party/python/psutil/psutil/_psposix.py поставляемый
Просмотреть файл

@ -1,5 +1,3 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -12,12 +10,15 @@ import os
import sys import sys
import time import time
from ._common import sdiskusage, usage_percent, memoize from ._common import memoize
from ._compat import PY3, unicode from ._common import sdiskusage
from ._common import usage_percent
from ._compat import PY3
from ._compat import unicode
from ._exceptions import TimeoutExpired
class TimeoutExpired(Exception): __all__ = ['pid_exists', 'wait_pid', 'disk_usage', 'get_terminal_map']
pass
def pid_exists(pid): def pid_exists(pid):
@ -48,7 +49,7 @@ def pid_exists(pid):
return True return True
def wait_pid(pid, timeout=None): def wait_pid(pid, timeout=None, proc_name=None):
"""Wait for process with pid 'pid' to terminate and return its """Wait for process with pid 'pid' to terminate and return its
exit status code as an integer. exit status code as an integer.
@ -62,7 +63,7 @@ def wait_pid(pid, timeout=None):
def check_timeout(delay): def check_timeout(delay):
if timeout is not None: if timeout is not None:
if timer() >= stop_at: if timer() >= stop_at:
raise TimeoutExpired() raise TimeoutExpired(timeout, pid=pid, name=proc_name)
time.sleep(delay) time.sleep(delay)
return min(delay * 2, 0.04) return min(delay * 2, 0.04)
@ -105,49 +106,74 @@ def wait_pid(pid, timeout=None):
# process exited due to a signal; return the integer of # process exited due to a signal; return the integer of
# that signal # that signal
if os.WIFSIGNALED(status): if os.WIFSIGNALED(status):
return os.WTERMSIG(status) return -os.WTERMSIG(status)
# process exited using exit(2) system call; return the # process exited using exit(2) system call; return the
# integer exit(2) system call has been called with # integer exit(2) system call has been called with
elif os.WIFEXITED(status): elif os.WIFEXITED(status):
return os.WEXITSTATUS(status) return os.WEXITSTATUS(status)
else: else:
# should never happen # should never happen
raise RuntimeError("unknown process exit status") raise ValueError("unknown process exit status %r" % status)
def disk_usage(path): def disk_usage(path):
"""Return disk usage associated with path.""" """Return disk usage associated with path.
try: Note: UNIX usually reserves 5% disk space which is not accessible
by user. In this function "total" and "used" values reflect the
total and used disk space whereas "free" and "percent" represent
the "free" and "used percent" user disk space.
"""
if PY3:
st = os.statvfs(path) st = os.statvfs(path)
except UnicodeEncodeError: else:
if not PY3 and isinstance(path, unicode): # os.statvfs() does not support unicode on Python 2:
# this is a bug with os.statvfs() and unicode on # - https://github.com/giampaolo/psutil/issues/416
# Python 2, see: # - http://bugs.python.org/issue18695
# - https://github.com/giampaolo/psutil/issues/416 try:
# - http://bugs.python.org/issue18695
try:
path = path.encode(sys.getfilesystemencoding())
except UnicodeEncodeError:
pass
st = os.statvfs(path) st = os.statvfs(path)
else: except UnicodeEncodeError:
raise if isinstance(path, unicode):
free = (st.f_bavail * st.f_frsize) try:
path = path.encode(sys.getfilesystemencoding())
except UnicodeEncodeError:
pass
st = os.statvfs(path)
else:
raise
# Total space which is only available to root (unless changed
# at system level).
total = (st.f_blocks * st.f_frsize) total = (st.f_blocks * st.f_frsize)
used = (st.f_blocks - st.f_bfree) * st.f_frsize # Remaining free space usable by root.
percent = usage_percent(used, total, _round=1) avail_to_root = (st.f_bfree * st.f_frsize)
# Remaining free space usable by user.
avail_to_user = (st.f_bavail * st.f_frsize)
# Total space being used in general.
used = (total - avail_to_root)
# Total space which is available to user (same as 'total' but
# for the user).
total_user = used + avail_to_user
# User usage percent compared to the total amount of space
# the user can use. This number would be higher if compared
# to root's because the user has less space (usually -5%).
usage_percent_user = usage_percent(used, total_user, _round=1)
# NB: the percentage is -5% than what shown by df due to # NB: the percentage is -5% than what shown by df due to
# reserved blocks that we are currently not considering: # reserved blocks that we are currently not considering:
# http://goo.gl/sWGbH # https://github.com/giampaolo/psutil/issues/829#issuecomment-223750462
return sdiskusage(total, used, free, percent) return sdiskusage(
total=total, used=used, free=avail_to_user, percent=usage_percent_user)
@memoize @memoize
def _get_terminal_map(): def get_terminal_map():
"""Get a map of device-id -> path as a dict.
Used by Process.terminal()
"""
ret = {} ret = {}
ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*') ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
for name in ls: for name in ls:
assert name not in ret assert name not in ret, name
try: try:
ret[os.stat(name).st_rdev] = name ret[os.stat(name).st_rdev] = name
except OSError as err: except OSError as err:

372
third_party/python/psutil/psutil/_pssunos.py поставляемый
Просмотреть файл

@ -1,5 +1,3 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -12,20 +10,36 @@ import socket
import subprocess import subprocess
import sys import sys
from collections import namedtuple from collections import namedtuple
from socket import AF_INET
from . import _common from . import _common
from . import _psposix from . import _psposix
from . import _psutil_posix as cext_posix from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext from . import _psutil_sunos as cext
from ._common import isfile_strict, socktype_to_enum, sockfam_to_enum from ._common import AF_INET6
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent from ._common import usage_percent
from ._compat import b
from ._compat import PY3 from ._compat import PY3
from ._exceptions import AccessDenied
from ._exceptions import NoSuchProcess
from ._exceptions import ZombieProcess
__extra__all__ = ["CONN_IDLE", "CONN_BOUND"] __extra__all__ = ["CONN_IDLE", "CONN_BOUND", "PROCFS_PATH"]
# =====================================================================
# --- globals
# =====================================================================
PAGE_SIZE = os.sysconf('SC_PAGE_SIZE') PAGE_SIZE = os.sysconf('SC_PAGE_SIZE')
AF_LINK = cext_posix.AF_LINK AF_LINK = cext_posix.AF_LINK
IS_64_BIT = sys.maxsize > 2**32
CONN_IDLE = "IDLE" CONN_IDLE = "IDLE"
CONN_BOUND = "BOUND" CONN_BOUND = "BOUND"
@ -57,29 +71,58 @@ TCP_STATUSES = {
cext.TCPS_BOUND: CONN_BOUND, # sunos specific cext.TCPS_BOUND: CONN_BOUND, # sunos specific
} }
proc_info_map = dict(
ppid=0,
rss=1,
vms=2,
create_time=3,
nice=4,
num_threads=5,
status=6,
ttynr=7)
# =====================================================================
# --- named tuples
# =====================================================================
# psutil.cpu_times()
scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait']) scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait'])
# psutil.cpu_times(percpu=True)
pcputimes = namedtuple('pcputimes',
['user', 'system', 'children_user', 'children_system'])
# psutil.virtual_memory()
svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free']) svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
pextmem = namedtuple('pextmem', ['rss', 'vms']) # psutil.Process.memory_info()
pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss', 'anon', 'locked']) pmem = namedtuple('pmem', ['rss', 'vms'])
pfullmem = pmem
# psutil.Process.memory_maps(grouped=True)
pmmap_grouped = namedtuple('pmmap_grouped',
['path', 'rss', 'anonymous', 'locked'])
# psutil.Process.memory_maps(grouped=False)
pmmap_ext = namedtuple( pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields)) 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
# set later from __init__.py
NoSuchProcess = None
ZombieProcess = None
AccessDenied = None
TimeoutExpired = None
# --- functions # =====================================================================
# --- utils
# =====================================================================
disk_io_counters = cext.disk_io_counters
net_io_counters = cext.net_io_counters def get_procfs_path():
disk_usage = _psposix.disk_usage """Return updated psutil.PROCFS_PATH constant."""
net_if_addrs = cext_posix.net_if_addrs return sys.modules['psutil'].PROCFS_PATH
# =====================================================================
# --- memory
# =====================================================================
def virtual_memory(): def virtual_memory():
# we could have done this with kstat, but imho this is good enough """Report virtual memory metrics."""
# we could have done this with kstat, but IMHO this is good enough
total = os.sysconf('SC_PHYS_PAGES') * PAGE_SIZE total = os.sysconf('SC_PHYS_PAGES') * PAGE_SIZE
# note: there's no difference on Solaris # note: there's no difference on Solaris
free = avail = os.sysconf('SC_AVPHYS_PAGES') * PAGE_SIZE free = avail = os.sysconf('SC_AVPHYS_PAGES') * PAGE_SIZE
@ -89,6 +132,7 @@ def virtual_memory():
def swap_memory(): def swap_memory():
"""Report swap memory metrics."""
sin, sout = cext.swap_mem() sin, sout = cext.swap_mem()
# XXX # XXX
# we are supposed to get total/free by doing so: # we are supposed to get total/free by doing so:
@ -97,13 +141,13 @@ def swap_memory():
# ...nevertheless I can't manage to obtain the same numbers as 'swap' # ...nevertheless I can't manage to obtain the same numbers as 'swap'
# cmdline utility, so let's parse its output (sigh!) # cmdline utility, so let's parse its output (sigh!)
p = subprocess.Popen(['/usr/bin/env', 'PATH=/usr/sbin:/sbin:%s' % p = subprocess.Popen(['/usr/bin/env', 'PATH=/usr/sbin:/sbin:%s' %
os.environ['PATH'], 'swap', '-l', '-k'], os.environ['PATH'], 'swap', '-l'],
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
if PY3: if PY3:
stdout = stdout.decode(sys.stdout.encoding) stdout = stdout.decode(sys.stdout.encoding)
if p.returncode != 0: if p.returncode != 0:
raise RuntimeError("'swap -l -k' failed (retcode=%s)" % p.returncode) raise RuntimeError("'swap -l' failed (retcode=%s)" % p.returncode)
lines = stdout.strip().split('\n')[1:] lines = stdout.strip().split('\n')[1:]
if not lines: if not lines:
@ -112,24 +156,17 @@ def swap_memory():
for line in lines: for line in lines:
line = line.split() line = line.split()
t, f = line[-2:] t, f = line[-2:]
t = t.replace('K', '') total += int(int(t) * 512)
f = f.replace('K', '') free += int(int(f) * 512)
total += int(int(t) * 1024)
free += int(int(f) * 1024)
used = total - free used = total - free
percent = usage_percent(used, total, _round=1) percent = usage_percent(used, total, _round=1)
return _common.sswap(total, used, free, percent, return _common.sswap(total, used, free, percent,
sin * PAGE_SIZE, sout * PAGE_SIZE) sin * PAGE_SIZE, sout * PAGE_SIZE)
def pids(): # =====================================================================
"""Returns a list of PIDs currently running on the system.""" # --- CPU
return [int(x) for x in os.listdir('/proc') if x.isdigit()] # =====================================================================
def pid_exists(pid):
"""Check for the existence of a unix pid."""
return _psposix.pid_exists(pid)
def cpu_times(): def cpu_times():
@ -158,28 +195,21 @@ def cpu_count_physical():
return cext.cpu_count_phys() return cext.cpu_count_phys()
def boot_time(): def cpu_stats():
"""The system boot time expressed in seconds since the epoch.""" """Return various CPU stats as a named tuple."""
return cext.boot_time() ctx_switches, interrupts, syscalls, traps = cext.cpu_stats()
soft_interrupts = 0
return _common.scpustats(ctx_switches, interrupts, soft_interrupts,
syscalls)
def users(): # =====================================================================
"""Return currently connected users as a list of namedtuples.""" # --- disks
retlist = [] # =====================================================================
rawlist = cext.users()
localhost = (':0.0', ':0')
for item in rawlist: disk_io_counters = cext.disk_io_counters
user, tty, hostname, tstamp, user_process = item disk_usage = _psposix.disk_usage
# note: the underlying C function includes entries about
# system boot, run level and others. We might want
# to use them in the future.
if not user_process:
continue
if hostname in localhost:
hostname = 'localhost'
nt = _common.suser(user, tty, hostname, tstamp)
retlist.append(nt)
return retlist
def disk_partitions(all=False): def disk_partitions(all=False):
@ -203,6 +233,15 @@ def disk_partitions(all=False):
return retlist return retlist
# =====================================================================
# --- network
# =====================================================================
net_io_counters = cext.net_io_counters
net_if_addrs = cext_posix.net_if_addrs
def net_connections(kind, _pid=-1): def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide """Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only). connections (as opposed to connections opened by one process only).
@ -215,7 +254,7 @@ def net_connections(kind, _pid=-1):
raise ValueError("invalid %r kind argument; choose between %s" raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in cmap]))) % (kind, ', '.join([repr(x) for x in cmap])))
families, types = _common.conn_tmap[kind] families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid, families, types) rawlist = cext.net_connections(_pid)
ret = set() ret = set()
for item in rawlist: for item in rawlist:
fd, fam, type_, laddr, raddr, status, pid = item fd, fam, type_, laddr, raddr, status, pid = item
@ -223,6 +262,11 @@ def net_connections(kind, _pid=-1):
continue continue
if type_ not in types: if type_ not in types:
continue continue
if fam in (AF_INET, AF_INET6):
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
status = TCP_STATUSES[status] status = TCP_STATUSES[status]
fam = sockfam_to_enum(fam) fam = sockfam_to_enum(fam)
type_ = socktype_to_enum(type_) type_ = socktype_to_enum(type_)
@ -245,18 +289,64 @@ def net_if_stats():
return ret return ret
# =====================================================================
# --- other system functions
# =====================================================================
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
return cext.boot_time()
def users():
"""Return currently connected users as a list of namedtuples."""
retlist = []
rawlist = cext.users()
localhost = (':0.0', ':0')
for item in rawlist:
user, tty, hostname, tstamp, user_process, pid = item
# note: the underlying C function includes entries about
# system boot, run level and others. We might want
# to use them in the future.
if not user_process:
continue
if hostname in localhost:
hostname = 'localhost'
nt = _common.suser(user, tty, hostname, tstamp, pid)
retlist.append(nt)
return retlist
# =====================================================================
# --- processes
# =====================================================================
def pids():
"""Returns a list of PIDs currently running on the system."""
return [int(x) for x in os.listdir(b(get_procfs_path())) if x.isdigit()]
def pid_exists(pid):
"""Check for the existence of a unix pid."""
return _psposix.pid_exists(pid)
def wrap_exceptions(fun): def wrap_exceptions(fun):
"""Call callable into a try/except clause and translate ENOENT, """Call callable into a try/except clause and translate ENOENT,
EACCES and EPERM in NoSuchProcess or AccessDenied exceptions. EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
""" """
def wrapper(self, *args, **kwargs): def wrapper(self, *args, **kwargs):
try: try:
return fun(self, *args, **kwargs) return fun(self, *args, **kwargs)
except EnvironmentError as err: except EnvironmentError as err:
# support for private module import if self.pid == 0:
if (NoSuchProcess is None or AccessDenied is None or if 0 in pids():
ZombieProcess is None): raise AccessDenied(self.pid, self._name)
raise else:
raise
# ENOENT (no such file or directory) gets raised on open(). # ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if # ESRCH (no such process) can get raised on read() if
# process is gone in meantime. # process is gone in meantime.
@ -274,21 +364,51 @@ def wrap_exceptions(fun):
class Process(object): class Process(object):
"""Wrapper class around underlying C implementation.""" """Wrapper class around underlying C implementation."""
__slots__ = ["pid", "_name", "_ppid"] __slots__ = ["pid", "_name", "_ppid", "_procfs_path"]
def __init__(self, pid): def __init__(self, pid):
self.pid = pid self.pid = pid
self._name = None self._name = None
self._ppid = None self._ppid = None
self._procfs_path = get_procfs_path()
def oneshot_enter(self):
self._proc_name_and_args.cache_activate()
self._proc_basic_info.cache_activate()
self._proc_cred.cache_activate()
def oneshot_exit(self):
self._proc_name_and_args.cache_deactivate()
self._proc_basic_info.cache_deactivate()
self._proc_cred.cache_deactivate()
@memoize_when_activated
def _proc_name_and_args(self):
return cext.proc_name_and_args(self.pid, self._procfs_path)
@memoize_when_activated
def _proc_basic_info(self):
ret = cext.proc_basic_info(self.pid, self._procfs_path)
assert len(ret) == len(proc_info_map)
return ret
@memoize_when_activated
def _proc_cred(self):
return cext.proc_cred(self.pid, self._procfs_path)
@wrap_exceptions @wrap_exceptions
def name(self): def name(self):
# note: max len == 15 # note: max len == 15
return cext.proc_name_and_args(self.pid)[0] return self._proc_name_and_args()[0]
@wrap_exceptions @wrap_exceptions
def exe(self): def exe(self):
# Will be guess later from cmdline but we want to explicitly try:
return os.readlink(
"%s/%s/path/a.out" % (self._procfs_path, self.pid))
except OSError:
pass # continue and guess the exe name from the cmdline
# Will be guessed later from cmdline but we want to explicitly
# invoke cmdline here in order to get an AccessDenied # invoke cmdline here in order to get an AccessDenied
# exception if the user has not enough privileges. # exception if the user has not enough privileges.
self.cmdline() self.cmdline()
@ -296,25 +416,34 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def cmdline(self): def cmdline(self):
return cext.proc_name_and_args(self.pid)[1].split(' ') return self._proc_name_and_args()[1].split(' ')
@wrap_exceptions
def environ(self):
return cext.proc_environ(self.pid, self._procfs_path)
@wrap_exceptions @wrap_exceptions
def create_time(self): def create_time(self):
return cext.proc_basic_info(self.pid)[3] return self._proc_basic_info()[proc_info_map['create_time']]
@wrap_exceptions @wrap_exceptions
def num_threads(self): def num_threads(self):
return cext.proc_basic_info(self.pid)[5] return self._proc_basic_info()[proc_info_map['num_threads']]
@wrap_exceptions @wrap_exceptions
def nice_get(self): def nice_get(self):
# For some reason getpriority(3) return ESRCH (no such process) # Note #1: for some reason getpriority(3) return ESRCH (no such
# for certain low-pid processes, no matter what (even as root). # process) for certain low-pid processes, no matter what (even
# as root).
# The process actually exists though, as it has a name, # The process actually exists though, as it has a name,
# creation time, etc. # creation time, etc.
# The best thing we can do here appears to be raising AD. # The best thing we can do here appears to be raising AD.
# Note: tested on Solaris 11; on Open Solaris 5 everything is # Note: tested on Solaris 11; on Open Solaris 5 everything is
# fine. # fine.
#
# Note #2: we also can get niceness from /proc/pid/psinfo
# but it's wrong, see:
# https://github.com/giampaolo/psutil/issues/1082
try: try:
return cext_posix.getpriority(self.pid) return cext_posix.getpriority(self.pid)
except EnvironmentError as err: except EnvironmentError as err:
@ -337,32 +466,52 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def ppid(self): def ppid(self):
return cext.proc_basic_info(self.pid)[0] self._ppid = self._proc_basic_info()[proc_info_map['ppid']]
return self._ppid
@wrap_exceptions @wrap_exceptions
def uids(self): def uids(self):
real, effective, saved, _, _, _ = cext.proc_cred(self.pid) real, effective, saved, _, _, _ = self._proc_cred()
return _common.puids(real, effective, saved) return _common.puids(real, effective, saved)
@wrap_exceptions @wrap_exceptions
def gids(self): def gids(self):
_, _, _, real, effective, saved = cext.proc_cred(self.pid) _, _, _, real, effective, saved = self._proc_cred()
return _common.puids(real, effective, saved) return _common.puids(real, effective, saved)
@wrap_exceptions @wrap_exceptions
def cpu_times(self): def cpu_times(self):
user, system = cext.proc_cpu_times(self.pid) try:
return _common.pcputimes(user, system) times = cext.proc_cpu_times(self.pid, self._procfs_path)
except OSError as err:
if err.errno == errno.EOVERFLOW and not IS_64_BIT:
# We may get here if we attempt to query a 64bit process
# with a 32bit python.
# Error originates from read() and also tools like "cat"
# fail in the same way (!).
# Since there simply is no way to determine CPU times we
# return 0.0 as a fallback. See:
# https://github.com/giampaolo/psutil/issues/857
times = (0.0, 0.0, 0.0, 0.0)
else:
raise
return _common.pcputimes(*times)
@wrap_exceptions
def cpu_num(self):
return cext.proc_cpu_num(self.pid, self._procfs_path)
@wrap_exceptions @wrap_exceptions
def terminal(self): def terminal(self):
procfs_path = self._procfs_path
hit_enoent = False hit_enoent = False
tty = wrap_exceptions( tty = wrap_exceptions(
cext.proc_basic_info(self.pid)[0]) self._proc_basic_info()[proc_info_map['ttynr']])
if tty != cext.PRNODEV: if tty != cext.PRNODEV:
for x in (0, 1, 2, 255): for x in (0, 1, 2, 255):
try: try:
return os.readlink('/proc/%d/path/%d' % (self.pid, x)) return os.readlink(
'%s/%d/path/%d' % (procfs_path, self.pid, x))
except OSError as err: except OSError as err:
if err.errno == errno.ENOENT: if err.errno == errno.ENOENT:
hit_enoent = True hit_enoent = True
@ -370,7 +519,7 @@ class Process(object):
raise raise
if hit_enoent: if hit_enoent:
# raise NSP if the process disappeared on us # raise NSP if the process disappeared on us
os.stat('/proc/%s' % self.pid) os.stat('%s/%s' % (procfs_path, self.pid))
@wrap_exceptions @wrap_exceptions
def cwd(self): def cwd(self):
@ -378,40 +527,51 @@ class Process(object):
# it exists (ls shows it). If that's the case and the process # it exists (ls shows it). If that's the case and the process
# is still alive return None (we can return None also on BSD). # is still alive return None (we can return None also on BSD).
# Reference: http://goo.gl/55XgO # Reference: http://goo.gl/55XgO
procfs_path = self._procfs_path
try: try:
return os.readlink("/proc/%s/path/cwd" % self.pid) return os.readlink("%s/%s/path/cwd" % (procfs_path, self.pid))
except OSError as err: except OSError as err:
if err.errno == errno.ENOENT: if err.errno == errno.ENOENT:
os.stat("/proc/%s" % self.pid) os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
return None return None
raise raise
@wrap_exceptions @wrap_exceptions
def memory_info(self): def memory_info(self):
ret = cext.proc_basic_info(self.pid) ret = self._proc_basic_info()
rss, vms = ret[1] * 1024, ret[2] * 1024 rss = ret[proc_info_map['rss']] * 1024
return _common.pmem(rss, vms) vms = ret[proc_info_map['vms']] * 1024
return pmem(rss, vms)
# it seems Solaris uses rss and vms only memory_full_info = memory_info
memory_info_ex = memory_info
@wrap_exceptions @wrap_exceptions
def status(self): def status(self):
code = cext.proc_basic_info(self.pid)[6] code = self._proc_basic_info()[proc_info_map['status']]
# XXX is '?' legit? (we're not supposed to return it anyway) # XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES.get(code, '?') return PROC_STATUSES.get(code, '?')
@wrap_exceptions @wrap_exceptions
def threads(self): def threads(self):
procfs_path = self._procfs_path
ret = [] ret = []
tids = os.listdir('/proc/%d/lwp' % self.pid) tids = os.listdir('%s/%d/lwp' % (procfs_path, self.pid))
hit_enoent = False hit_enoent = False
for tid in tids: for tid in tids:
tid = int(tid) tid = int(tid)
try: try:
utime, stime = cext.query_process_thread( utime, stime = cext.query_process_thread(
self.pid, tid) self.pid, tid, procfs_path)
except EnvironmentError as err: except EnvironmentError as err:
if err.errno == errno.EOVERFLOW and not IS_64_BIT:
# We may get here if we attempt to query a 64bit process
# with a 32bit python.
# Error originates from read() and also tools like "cat"
# fail in the same way (!).
# Since there simply is no way to determine CPU times we
# return 0.0 as a fallback. See:
# https://github.com/giampaolo/psutil/issues/857
continue
# ENOENT == thread gone in meantime # ENOENT == thread gone in meantime
if err.errno == errno.ENOENT: if err.errno == errno.ENOENT:
hit_enoent = True hit_enoent = True
@ -422,15 +582,16 @@ class Process(object):
ret.append(nt) ret.append(nt)
if hit_enoent: if hit_enoent:
# raise NSP if the process disappeared on us # raise NSP if the process disappeared on us
os.stat('/proc/%s' % self.pid) os.stat('%s/%s' % (procfs_path, self.pid))
return ret return ret
@wrap_exceptions @wrap_exceptions
def open_files(self): def open_files(self):
retlist = [] retlist = []
hit_enoent = False hit_enoent = False
pathdir = '/proc/%d/path' % self.pid procfs_path = self._procfs_path
for fd in os.listdir('/proc/%d/fd' % self.pid): pathdir = '%s/%d/path' % (procfs_path, self.pid)
for fd in os.listdir('%s/%d/fd' % (procfs_path, self.pid)):
path = os.path.join(pathdir, fd) path = os.path.join(pathdir, fd)
if os.path.islink(path): if os.path.islink(path):
try: try:
@ -446,7 +607,7 @@ class Process(object):
retlist.append(_common.popenfile(file, int(fd))) retlist.append(_common.popenfile(file, int(fd)))
if hit_enoent: if hit_enoent:
# raise NSP if the process disappeared on us # raise NSP if the process disappeared on us
os.stat('/proc/%s' % self.pid) os.stat('%s/%s' % (procfs_path, self.pid))
return retlist return retlist
def _get_unix_sockets(self, pid): def _get_unix_sockets(self, pid):
@ -490,7 +651,8 @@ class Process(object):
# process is no longer active so we force NSP in case the PID # process is no longer active so we force NSP in case the PID
# is no longer there. # is no longer there.
if not ret: if not ret:
os.stat('/proc/%s' % self.pid) # will raise NSP if process is gone # will raise NSP if process is gone
os.stat('%s/%s' % (self._procfs_path, self.pid))
# UNIX sockets # UNIX sockets
if kind in ('all', 'unix'): if kind in ('all', 'unix'):
@ -507,15 +669,30 @@ class Process(object):
return '%s-%s' % (hex(start)[2:].strip('L'), return '%s-%s' % (hex(start)[2:].strip('L'),
hex(end)[2:].strip('L')) hex(end)[2:].strip('L'))
procfs_path = self._procfs_path
retlist = [] retlist = []
rawlist = cext.proc_memory_maps(self.pid) try:
rawlist = cext.proc_memory_maps(self.pid, procfs_path)
except OSError as err:
if err.errno == errno.EOVERFLOW and not IS_64_BIT:
# We may get here if we attempt to query a 64bit process
# with a 32bit python.
# Error originates from read() and also tools like "cat"
# fail in the same way (!).
# Since there simply is no way to determine CPU times we
# return 0.0 as a fallback. See:
# https://github.com/giampaolo/psutil/issues/857
return []
else:
raise
hit_enoent = False hit_enoent = False
for item in rawlist: for item in rawlist:
addr, addrsize, perm, name, rss, anon, locked = item addr, addrsize, perm, name, rss, anon, locked = item
addr = toaddr(addr, addrsize) addr = toaddr(addr, addrsize)
if not name.startswith('['): if not name.startswith('['):
try: try:
name = os.readlink('/proc/%s/path/%s' % (self.pid, name)) name = os.readlink(
'%s/%s/path/%s' % (procfs_path, self.pid, name))
except OSError as err: except OSError as err:
if err.errno == errno.ENOENT: if err.errno == errno.ENOENT:
# sometimes the link may not be resolved by # sometimes the link may not be resolved by
@ -524,30 +701,25 @@ class Process(object):
# unresolved link path. # unresolved link path.
# This seems an incosistency with /proc similar # This seems an incosistency with /proc similar
# to: http://goo.gl/55XgO # to: http://goo.gl/55XgO
name = '/proc/%s/path/%s' % (self.pid, name) name = '%s/%s/path/%s' % (procfs_path, self.pid, name)
hit_enoent = True hit_enoent = True
else: else:
raise raise
retlist.append((addr, perm, name, rss, anon, locked)) retlist.append((addr, perm, name, rss, anon, locked))
if hit_enoent: if hit_enoent:
# raise NSP if the process disappeared on us # raise NSP if the process disappeared on us
os.stat('/proc/%s' % self.pid) os.stat('%s/%s' % (procfs_path, self.pid))
return retlist return retlist
@wrap_exceptions @wrap_exceptions
def num_fds(self): def num_fds(self):
return len(os.listdir("/proc/%s/fd" % self.pid)) return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
@wrap_exceptions @wrap_exceptions
def num_ctx_switches(self): def num_ctx_switches(self):
return _common.pctxsw(*cext.proc_num_ctx_switches(self.pid)) return _common.pctxsw(
*cext.proc_num_ctx_switches(self.pid, self._procfs_path))
@wrap_exceptions @wrap_exceptions
def wait(self, timeout=None): def wait(self, timeout=None):
try: return _psposix.wait_pid(self.pid, timeout, self._name)
return _psposix.wait_pid(self.pid, timeout)
except _psposix.TimeoutExpired:
# support for private module import
if TimeoutExpired is None:
raise
raise TimeoutExpired(timeout, self.pid, self._name)

2296
third_party/python/psutil/psutil/_psutil_bsd.c поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,53 +0,0 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
// --- per-process functions
static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
static PyObject* psutil_proc_connections(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
static PyObject* psutil_proc_gids(PyObject* self, PyObject* args);
static PyObject* psutil_proc_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_ctx_switches(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
static PyObject* psutil_proc_ppid(PyObject* self, PyObject* args);
static PyObject* psutil_proc_status(PyObject* self, PyObject* args);
static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
static PyObject* psutil_proc_tty_nr(PyObject* self, PyObject* args);
static PyObject* psutil_proc_uids(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
#endif
// --- system-related functions
static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_pids(PyObject* self, PyObject* args);
static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
static PyObject* psutil_users(PyObject* self, PyObject* args);
static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
#endif

Просмотреть файл

@ -7,16 +7,43 @@
*/ */
#include <Python.h> #include <Python.h>
#include <stdio.h>
// Global vars.
int PSUTIL_DEBUG = 0;
int PSUTIL_TESTING = 0;
/*
* Backport of unicode FS APIs from Python 3.
* On Python 2 we just return a plain byte string
* which is never supposed to raise decoding errors.
* See: https://github.com/giampaolo/psutil/issues/1040
*/
#if PY_MAJOR_VERSION < 3
PyObject *
PyUnicode_DecodeFSDefault(char *s) {
return PyString_FromString(s);
}
PyObject *
PyUnicode_DecodeFSDefaultAndSize(char *s, Py_ssize_t size) {
return PyString_FromStringAndSize(s, size);
}
#endif
/* /*
* Set OSError(errno=ESRCH, strerror="No such process") Python exception. * Set OSError(errno=ESRCH, strerror="No such process") Python exception.
* If msg != "" the exception message will change in accordance.
*/ */
PyObject * PyObject *
NoSuchProcess(void) { NoSuchProcess(char *msg) {
PyObject *exc; PyObject *exc;
char *msg = strerror(ESRCH); exc = PyObject_CallFunction(
exc = PyObject_CallFunction(PyExc_OSError, "(is)", ESRCH, msg); PyExc_OSError, "(is)", ESRCH, strlen(msg) ? msg : strerror(ESRCH));
PyErr_SetObject(PyExc_OSError, exc); PyErr_SetObject(PyExc_OSError, exc);
Py_XDECREF(exc); Py_XDECREF(exc);
return NULL; return NULL;
@ -25,13 +52,53 @@ NoSuchProcess(void) {
/* /*
* Set OSError(errno=EACCES, strerror="Permission denied") Python exception. * Set OSError(errno=EACCES, strerror="Permission denied") Python exception.
* If msg != "" the exception message will change in accordance.
*/ */
PyObject * PyObject *
AccessDenied(void) { AccessDenied(char *msg) {
PyObject *exc; PyObject *exc;
char *msg = strerror(EACCES); exc = PyObject_CallFunction(
exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg); PyExc_OSError, "(is)", EACCES, strlen(msg) ? msg : strerror(EACCES));
PyErr_SetObject(PyExc_OSError, exc); PyErr_SetObject(PyExc_OSError, exc);
Py_XDECREF(exc); Py_XDECREF(exc);
return NULL; return NULL;
} }
/*
* Enable testing mode. This has the same effect as setting PSUTIL_TESTING
* env var. This dual method exists because updating os.environ on
* Windows has no effect. Called on unit tests setup.
*/
PyObject *
psutil_set_testing(PyObject *self, PyObject *args) {
PSUTIL_TESTING = 1;
Py_INCREF(Py_None);
return Py_None;
}
/*
* Print a debug message on stderr. No-op if PSUTIL_DEBUG env var is not set.
*/
void
psutil_debug(const char* format, ...) {
va_list argptr;
va_start(argptr, format);
fprintf(stderr, "psutil-dubug> ");
vfprintf(stderr, format, argptr);
fprintf(stderr, "\n");
va_end(argptr);
}
/*
* Called on module import on all platforms.
*/
void
psutil_setup(void) {
if (getenv("PSUTIL_DEBUG") != NULL)
PSUTIL_DEBUG = 1;
if (getenv("PSUTIL_TESTING") != NULL)
PSUTIL_TESTING = 1;
}

Просмотреть файл

@ -6,5 +6,20 @@
#include <Python.h> #include <Python.h>
PyObject* AccessDenied(void); extern int PSUTIL_TESTING;
PyObject* NoSuchProcess(void); extern int PSUTIL_DEBUG;
// a signaler for connections without an actual status
static const int PSUTIL_CONN_NONE = 128;
#if PY_MAJOR_VERSION < 3
PyObject* PyUnicode_DecodeFSDefault(char *s);
PyObject* PyUnicode_DecodeFSDefaultAndSize(char *s, Py_ssize_t size);
#endif
PyObject* AccessDenied(char *msg);
PyObject* NoSuchProcess(char *msg);
PyObject* psutil_set_testing(PyObject *self, PyObject *args);
void psutil_debug(const char* format, ...);
void psutil_setup(void);

Просмотреть файл

@ -23,9 +23,18 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/ethtool.h>
#include "_psutil_linux.h" // see: https://github.com/giampaolo/psutil/issues/659
#ifdef PSUTIL_ETHTOOL_MISSING_TYPES
#include <linux/types.h>
typedef __u64 u64;
typedef __u32 u32;
typedef __u16 u16;
typedef __u8 u8;
#endif
/* Avoid redefinition of struct sysinfo with musl libc */
#define _LINUX_SYSINFO_H
#include <linux/ethtool.h>
/* The minimum number of CPUs allocated in a cpu_set_t */ /* The minimum number of CPUs allocated in a cpu_set_t */
static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
@ -45,11 +54,8 @@ static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#include "_psutil_common.h"
#if PSUTIL_HAVE_IOPRIO #include "_psutil_posix.h"
enum {
IOPRIO_WHO_PROCESS = 1,
};
// May happen on old RedHat versions, see: // May happen on old RedHat versions, see:
// https://github.com/giampaolo/psutil/issues/607 // https://github.com/giampaolo/psutil/issues/607
@ -57,15 +63,19 @@ enum {
#define DUPLEX_UNKNOWN 0xff #define DUPLEX_UNKNOWN 0xff
#endif #endif
#if PSUTIL_HAVE_IOPRIO
enum {
IOPRIO_WHO_PROCESS = 1,
};
static inline int static inline int
ioprio_get(int which, int who) ioprio_get(int which, int who) {
{
return syscall(__NR_ioprio_get, which, who); return syscall(__NR_ioprio_get, which, who);
} }
static inline int static inline int
ioprio_set(int which, int who, int ioprio) ioprio_set(int which, int who, int ioprio) {
{
return syscall(__NR_ioprio_set, which, who, ioprio); return syscall(__NR_ioprio_set, which, who, ioprio);
} }
@ -81,8 +91,7 @@ ioprio_set(int which, int who, int ioprio)
* Return a (ioclass, iodata) Python tuple representing process I/O priority. * Return a (ioclass, iodata) Python tuple representing process I/O priority.
*/ */
static PyObject * static PyObject *
psutil_proc_ioprio_get(PyObject *self, PyObject *args) psutil_proc_ioprio_get(PyObject *self, PyObject *args) {
{
long pid; long pid;
int ioprio, ioclass, iodata; int ioprio, ioclass, iodata;
if (! PyArg_ParseTuple(args, "l", &pid)) if (! PyArg_ParseTuple(args, "l", &pid))
@ -102,8 +111,7 @@ psutil_proc_ioprio_get(PyObject *self, PyObject *args)
* or 0. iodata goes from 0 to 7 depending on ioclass specified. * or 0. iodata goes from 0 to 7 depending on ioclass specified.
*/ */
static PyObject * static PyObject *
psutil_proc_ioprio_set(PyObject *self, PyObject *args) psutil_proc_ioprio_set(PyObject *self, PyObject *args) {
{
long pid; long pid;
int ioprio, ioclass, iodata; int ioprio, ioclass, iodata;
int retval; int retval;
@ -126,20 +134,19 @@ psutil_proc_ioprio_set(PyObject *self, PyObject *args)
* 'soft' and 'hard' args must be provided. * 'soft' and 'hard' args must be provided.
*/ */
static PyObject * static PyObject *
psutil_linux_prlimit(PyObject *self, PyObject *args) psutil_linux_prlimit(PyObject *self, PyObject *args) {
{
long pid; long pid;
int ret, resource; int ret, resource;
struct rlimit old, new; struct rlimit old, new;
struct rlimit *newp = NULL; struct rlimit *newp = NULL;
PyObject *soft = NULL; PyObject *py_soft = NULL;
PyObject *hard = NULL; PyObject *py_hard = NULL;
if (! PyArg_ParseTuple(args, "li|OO", &pid, &resource, &soft, &hard)) if (! PyArg_ParseTuple(args, "li|OO", &pid, &resource, &py_soft, &py_hard))
return NULL; return NULL;
// get // get
if (soft == NULL && hard == NULL) { if (py_soft == NULL && py_hard == NULL) {
ret = prlimit(pid, resource, NULL, &old); ret = prlimit(pid, resource, NULL, &old);
if (ret == -1) if (ret == -1)
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
@ -156,17 +163,17 @@ psutil_linux_prlimit(PyObject *self, PyObject *args)
// set // set
else { else {
#if defined(PSUTIL_HAVE_LARGEFILE_SUPPORT) #if defined(PSUTIL_HAVE_LARGEFILE_SUPPORT)
new.rlim_cur = PyLong_AsLongLong(soft); new.rlim_cur = PyLong_AsLongLong(py_soft);
if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred()) if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
return NULL; return NULL;
new.rlim_max = PyLong_AsLongLong(hard); new.rlim_max = PyLong_AsLongLong(py_hard);
if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred()) if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
return NULL; return NULL;
#else #else
new.rlim_cur = PyLong_AsLong(soft); new.rlim_cur = PyLong_AsLong(py_soft);
if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred()) if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
return NULL; return NULL;
new.rlim_max = PyLong_AsLong(hard); new.rlim_max = PyLong_AsLong(py_hard);
if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred()) if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
return NULL; return NULL;
#endif #endif
@ -185,12 +192,13 @@ psutil_linux_prlimit(PyObject *self, PyObject *args)
* mount point and filesystem type * mount point and filesystem type
*/ */
static PyObject * static PyObject *
psutil_disk_partitions(PyObject *self, PyObject *args) psutil_disk_partitions(PyObject *self, PyObject *args) {
{
FILE *file = NULL; FILE *file = NULL;
struct mntent *entry; struct mntent *entry;
PyObject *py_retlist = PyList_New(0); PyObject *py_dev = NULL;
PyObject *py_mountp = NULL;
PyObject *py_tuple = NULL; PyObject *py_tuple = NULL;
PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL) if (py_retlist == NULL)
return NULL; return NULL;
@ -206,18 +214,26 @@ psutil_disk_partitions(PyObject *self, PyObject *args)
while ((entry = getmntent(file))) { while ((entry = getmntent(file))) {
if (entry == NULL) { if (entry == NULL) {
PyErr_Format(PyExc_RuntimeError, "getmntent() failed"); PyErr_Format(PyExc_RuntimeError, "getmntent() syscall failed");
goto error; goto error;
} }
py_tuple = Py_BuildValue("(ssss)", py_dev = PyUnicode_DecodeFSDefault(entry->mnt_fsname);
entry->mnt_fsname, // device if (! py_dev)
entry->mnt_dir, // mount point goto error;
py_mountp = PyUnicode_DecodeFSDefault(entry->mnt_dir);
if (! py_mountp)
goto error;
py_tuple = Py_BuildValue("(OOss)",
py_dev, // device
py_mountp, // mount point
entry->mnt_type, // fs type entry->mnt_type, // fs type
entry->mnt_opts); // options entry->mnt_opts); // options
if (! py_tuple) if (! py_tuple)
goto error; goto error;
if (PyList_Append(py_retlist, py_tuple)) if (PyList_Append(py_retlist, py_tuple))
goto error; goto error;
Py_DECREF(py_dev);
Py_DECREF(py_mountp);
Py_DECREF(py_tuple); Py_DECREF(py_tuple);
} }
endmntent(file); endmntent(file);
@ -226,6 +242,8 @@ psutil_disk_partitions(PyObject *self, PyObject *args)
error: error:
if (file != NULL) if (file != NULL)
endmntent(file); endmntent(file);
Py_XDECREF(py_dev);
Py_XDECREF(py_mountp);
Py_XDECREF(py_tuple); Py_XDECREF(py_tuple);
Py_DECREF(py_retlist); Py_DECREF(py_retlist);
return NULL; return NULL;
@ -236,21 +254,22 @@ error:
* A wrapper around sysinfo(), return system memory usage statistics. * A wrapper around sysinfo(), return system memory usage statistics.
*/ */
static PyObject * static PyObject *
psutil_linux_sysinfo(PyObject *self, PyObject *args) psutil_linux_sysinfo(PyObject *self, PyObject *args) {
{
struct sysinfo info; struct sysinfo info;
if (sysinfo(&info) != 0) if (sysinfo(&info) != 0)
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
// note: boot time might also be determined from here // note: boot time might also be determined from here
return Py_BuildValue( return Py_BuildValue(
"(KKKKKK)", "(kkkkkkI)",
(unsigned long long)info.totalram * info.mem_unit, // total info.totalram, // total
(unsigned long long)info.freeram * info.mem_unit, // free info.freeram, // free
(unsigned long long)info.bufferram * info.mem_unit, // buffer info.bufferram, // buffer
(unsigned long long)info.sharedram * info.mem_unit, // shared info.sharedram, // shared
(unsigned long long)info.totalswap * info.mem_unit, // swap tot info.totalswap, // swap tot
(unsigned long long)info.freeswap * info.mem_unit); // swap free info.freeswap, // swap free
info.mem_unit // multiplier
);
} }
@ -263,15 +282,14 @@ psutil_linux_sysinfo(PyObject *self, PyObject *args)
#ifdef CPU_ALLOC #ifdef CPU_ALLOC
static PyObject * static PyObject *
psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) {
{
int cpu, ncpus, count, cpucount_s; int cpu, ncpus, count, cpucount_s;
long pid; long pid;
size_t setsize; size_t setsize;
cpu_set_t *mask = NULL; cpu_set_t *mask = NULL;
PyObject *res = NULL; PyObject *py_list = NULL;
if (!PyArg_ParseTuple(args, "i", &pid)) if (!PyArg_ParseTuple(args, "l", &pid))
return NULL; return NULL;
ncpus = NCPUS_START; ncpus = NCPUS_START;
while (1) { while (1) {
@ -292,8 +310,8 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
ncpus = ncpus * 2; ncpus = ncpus * 2;
} }
res = PyList_New(0); py_list = PyList_New(0);
if (res == NULL) if (py_list == NULL)
goto error; goto error;
cpucount_s = CPU_COUNT_S(setsize, mask); cpucount_s = CPU_COUNT_S(setsize, mask);
@ -306,7 +324,7 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
#endif #endif
if (cpu_num == NULL) if (cpu_num == NULL)
goto error; goto error;
if (PyList_Append(res, cpu_num)) { if (PyList_Append(py_list, cpu_num)) {
Py_DECREF(cpu_num); Py_DECREF(cpu_num);
goto error; goto error;
} }
@ -315,12 +333,12 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
} }
} }
CPU_FREE(mask); CPU_FREE(mask);
return res; return py_list;
error: error:
if (mask) if (mask)
CPU_FREE(mask); CPU_FREE(mask);
Py_XDECREF(res); Py_XDECREF(py_list);
return NULL; return NULL;
} }
#else #else
@ -330,8 +348,7 @@ error:
* Alternative implementation in case CPU_ALLOC is not defined. * Alternative implementation in case CPU_ALLOC is not defined.
*/ */
static PyObject * static PyObject *
psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) {
{
cpu_set_t cpuset; cpu_set_t cpuset;
unsigned int len = sizeof(cpu_set_t); unsigned int len = sizeof(cpu_set_t);
long pid; long pid;
@ -339,7 +356,7 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
PyObject* py_retlist = NULL; PyObject* py_retlist = NULL;
PyObject *py_cpu_num = NULL; PyObject *py_cpu_num = NULL;
if (!PyArg_ParseTuple(args, "i", &pid)) if (!PyArg_ParseTuple(args, "l", &pid))
return NULL; return NULL;
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
if (sched_getaffinity(pid, len, &cpuset) < 0) if (sched_getaffinity(pid, len, &cpuset) < 0)
@ -363,7 +380,7 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
error: error:
Py_XDECREF(py_cpu_num); Py_XDECREF(py_cpu_num);
Py_DECREF(py_retlist); Py_XDECREF(py_retlist);
return NULL; return NULL;
} }
#endif #endif
@ -372,8 +389,7 @@ error:
* Set process CPU affinity; expects a bitmask * Set process CPU affinity; expects a bitmask
*/ */
static PyObject * static PyObject *
psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
{
cpu_set_t cpu_set; cpu_set_t cpu_set;
size_t len; size_t len;
long pid; long pid;
@ -402,11 +418,15 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args)
#else #else
long value = PyInt_AsLong(item); long value = PyInt_AsLong(item);
#endif #endif
if (value == -1 && PyErr_Occurred()) if ((value == -1) || PyErr_Occurred()) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_ValueError, "invalid CPU value");
goto error; goto error;
}
CPU_SET(value, &cpu_set); CPU_SET(value, &cpu_set);
} }
len = sizeof(cpu_set); len = sizeof(cpu_set);
if (sched_setaffinity(pid, len, &cpu_set)) { if (sched_setaffinity(pid, len, &cpu_set)) {
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
@ -427,44 +447,61 @@ error:
* Return currently connected users as a list of tuples. * Return currently connected users as a list of tuples.
*/ */
static PyObject * static PyObject *
psutil_users(PyObject *self, PyObject *args) psutil_users(PyObject *self, PyObject *args) {
{
PyObject *ret_list = PyList_New(0);
PyObject *tuple = NULL;
PyObject *user_proc = NULL;
struct utmp *ut; struct utmp *ut;
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
PyObject *py_username = NULL;
PyObject *py_tty = NULL;
PyObject *py_hostname = NULL;
PyObject *py_user_proc = NULL;
if (ret_list == NULL) if (py_retlist == NULL)
return NULL; return NULL;
setutent(); setutent();
while (NULL != (ut = getutent())) { while (NULL != (ut = getutent())) {
tuple = NULL; py_tuple = NULL;
user_proc = NULL; py_user_proc = NULL;
if (ut->ut_type == USER_PROCESS) if (ut->ut_type == USER_PROCESS)
user_proc = Py_True; py_user_proc = Py_True;
else else
user_proc = Py_False; py_user_proc = Py_False;
tuple = Py_BuildValue( py_username = PyUnicode_DecodeFSDefault(ut->ut_user);
"(sssfO)", if (! py_username)
ut->ut_user, // username goto error;
ut->ut_line, // tty py_tty = PyUnicode_DecodeFSDefault(ut->ut_line);
ut->ut_host, // hostname if (! py_tty)
goto error;
py_hostname = PyUnicode_DecodeFSDefault(ut->ut_host);
if (! py_hostname)
goto error;
py_tuple = Py_BuildValue(
"(OOOfOi)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)ut->ut_tv.tv_sec, // tstamp (float)ut->ut_tv.tv_sec, // tstamp
user_proc // (bool) user process py_user_proc, // (bool) user process
ut->ut_pid // process id
); );
if (! tuple) if (! py_tuple)
goto error; goto error;
if (PyList_Append(ret_list, tuple)) if (PyList_Append(py_retlist, py_tuple))
goto error; goto error;
Py_DECREF(tuple); Py_DECREF(py_username);
Py_DECREF(py_tty);
Py_DECREF(py_hostname);
Py_DECREF(py_tuple);
} }
endutent(); endutent();
return ret_list; return py_retlist;
error: error:
Py_XDECREF(tuple); Py_XDECREF(py_username);
Py_XDECREF(user_proc); Py_XDECREF(py_tty);
Py_DECREF(ret_list); Py_XDECREF(py_hostname);
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
endutent(); endutent();
return NULL; return NULL;
} }
@ -477,18 +514,15 @@ error:
* http://www.i-scream.org/libstatgrab/ * http://www.i-scream.org/libstatgrab/
*/ */
static PyObject* static PyObject*
psutil_net_if_stats(PyObject* self, PyObject* args) psutil_net_if_duplex_speed(PyObject* self, PyObject* args) {
{
char *nic_name; char *nic_name;
int sock = 0; int sock = 0;
int ret; int ret;
int duplex; int duplex;
int speed; int speed;
int mtu;
struct ifreq ifr; struct ifreq ifr;
struct ethtool_cmd ethcmd; struct ethtool_cmd ethcmd;
PyObject *py_is_up = NULL; PyObject *py_retlist = NULL;
PyObject *py_ret = NULL;
if (! PyArg_ParseTuple(args, "s", &nic_name)) if (! PyArg_ParseTuple(args, "s", &nic_name))
return NULL; return NULL;
@ -498,26 +532,10 @@ psutil_net_if_stats(PyObject* self, PyObject* args)
goto error; goto error;
strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
// is up?
ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
if (ret == -1)
goto error;
if ((ifr.ifr_flags & IFF_UP) != 0)
py_is_up = Py_True;
else
py_is_up = Py_False;
Py_INCREF(py_is_up);
// MTU
ret = ioctl(sock, SIOCGIFMTU, &ifr);
if (ret == -1)
goto error;
mtu = ifr.ifr_mtu;
// duplex and speed // duplex and speed
memset(&ethcmd, 0, sizeof ethcmd); memset(&ethcmd, 0, sizeof ethcmd);
ethcmd.cmd = ETHTOOL_GSET; ethcmd.cmd = ETHTOOL_GSET;
ifr.ifr_data = (caddr_t)&ethcmd; ifr.ifr_data = (void *)&ethcmd;
ret = ioctl(sock, SIOCETHTOOL, &ifr); ret = ioctl(sock, SIOCETHTOOL, &ifr);
if (ret != -1) { if (ret != -1) {
@ -525,8 +543,11 @@ psutil_net_if_stats(PyObject* self, PyObject* args)
speed = ethcmd.speed; speed = ethcmd.speed;
} }
else { else {
if (errno == EOPNOTSUPP) { if ((errno == EOPNOTSUPP) || (errno == EINVAL)) {
// we typically get here in case of wi-fi cards // EOPNOTSUPP may occur in case of wi-fi cards.
// For EINVAL see:
// https://github.com/giampaolo/psutil/issues/797
// #issuecomment-202999532
duplex = DUPLEX_UNKNOWN; duplex = DUPLEX_UNKNOWN;
speed = 0; speed = 0;
} }
@ -536,18 +557,15 @@ psutil_net_if_stats(PyObject* self, PyObject* args)
} }
close(sock); close(sock);
py_ret = Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu); py_retlist = Py_BuildValue("[ii]", duplex, speed);
if (!py_ret) if (!py_retlist)
goto error; goto error;
Py_DECREF(py_is_up); return py_retlist;
return py_ret;
error: error:
Py_XDECREF(py_is_up); if (sock != -1)
if (sock != 0)
close(sock); close(sock);
PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
return NULL;
} }
@ -555,8 +573,7 @@ error:
* Define the psutil C module methods and initialize the module. * Define the psutil C module methods and initialize the module.
*/ */
static PyMethodDef static PyMethodDef
PsutilMethods[] = PsutilMethods[] = {
{
// --- per-process functions // --- per-process functions
#if PSUTIL_HAVE_IOPRIO #if PSUTIL_HAVE_IOPRIO
@ -577,8 +594,8 @@ PsutilMethods[] =
"device, mount point and filesystem type"}, "device, mount point and filesystem type"},
{"users", psutil_users, METH_VARARGS, {"users", psutil_users, METH_VARARGS,
"Return currently connected users as a list of tuples"}, "Return currently connected users as a list of tuples"},
{"net_if_stats", psutil_net_if_stats, METH_VARARGS, {"net_if_duplex_speed", psutil_net_if_duplex_speed, METH_VARARGS,
"Return NIC stats (isup, duplex, speed, mtu)"}, "Return duplex and speed info about a NIC"},
// --- linux specific // --- linux specific
@ -589,6 +606,9 @@ PsutilMethods[] =
"Get or set process resource limits."}, "Get or set process resource limits."},
#endif #endif
// --- others
{"set_testing", psutil_set_testing, METH_NOARGS,
"Set psutil in testing mode"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -640,16 +660,15 @@ PyMODINIT_FUNC PyInit__psutil_linux(void)
void init_psutil_linux(void) void init_psutil_linux(void)
#endif #endif
{ {
PyObject *v;
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create(&moduledef); PyObject *module = PyModule_Create(&moduledef);
#else #else
PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods); PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods);
#endif #endif
PyModule_AddIntConstant(module, "version", PSUTIL_VERSION); PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
#if PSUTIL_HAVE_PRLIMIT #if PSUTIL_HAVE_PRLIMIT
PyModule_AddIntConstant(module, "RLIM_INFINITY", RLIM_INFINITY);
PyModule_AddIntConstant(module, "RLIMIT_AS", RLIMIT_AS); PyModule_AddIntConstant(module, "RLIMIT_AS", RLIMIT_AS);
PyModule_AddIntConstant(module, "RLIMIT_CORE", RLIMIT_CORE); PyModule_AddIntConstant(module, "RLIMIT_CORE", RLIMIT_CORE);
PyModule_AddIntConstant(module, "RLIMIT_CPU", RLIMIT_CPU); PyModule_AddIntConstant(module, "RLIMIT_CPU", RLIMIT_CPU);
@ -661,6 +680,19 @@ void init_psutil_linux(void)
PyModule_AddIntConstant(module, "RLIMIT_NPROC", RLIMIT_NPROC); PyModule_AddIntConstant(module, "RLIMIT_NPROC", RLIMIT_NPROC);
PyModule_AddIntConstant(module, "RLIMIT_RSS", RLIMIT_RSS); PyModule_AddIntConstant(module, "RLIMIT_RSS", RLIMIT_RSS);
PyModule_AddIntConstant(module, "RLIMIT_STACK", RLIMIT_STACK); PyModule_AddIntConstant(module, "RLIMIT_STACK", RLIMIT_STACK);
#if defined(HAVE_LONG_LONG)
if (sizeof(RLIM_INFINITY) > sizeof(long)) {
v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY);
} else
#endif
{
v = PyLong_FromLong((long) RLIM_INFINITY);
}
if (v) {
PyModule_AddObject(module, "RLIM_INFINITY", v);
}
#ifdef RLIMIT_MSGQUEUE #ifdef RLIMIT_MSGQUEUE
PyModule_AddIntConstant(module, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE); PyModule_AddIntConstant(module, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
#endif #endif
@ -681,6 +713,8 @@ void init_psutil_linux(void)
PyModule_AddIntConstant(module, "DUPLEX_FULL", DUPLEX_FULL); PyModule_AddIntConstant(module, "DUPLEX_FULL", DUPLEX_FULL);
PyModule_AddIntConstant(module, "DUPLEX_UNKNOWN", DUPLEX_UNKNOWN); PyModule_AddIntConstant(module, "DUPLEX_UNKNOWN", DUPLEX_UNKNOWN);
psutil_setup();
if (module == NULL) if (module == NULL)
INITERROR; INITERROR;
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3

Просмотреть файл

@ -1,21 +0,0 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
// process
static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
static PyObject* psutil_proc_ioprio_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_ioprio_get(PyObject* self, PyObject* args);
// system
static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
static PyObject* psutil_linux_sysinfo(PyObject* self, PyObject* args);
static PyObject* psutil_users(PyObject* self, PyObject* args);
static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);

1148
third_party/python/psutil/psutil/_psutil_osx.c поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,41 +0,0 @@
/*
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
// --- per-process functions
static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
static PyObject* psutil_proc_connections(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
static PyObject* psutil_proc_gids(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
static PyObject* psutil_proc_ppid(PyObject* self, PyObject* args);
static PyObject* psutil_proc_status(PyObject* self, PyObject* args);
static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
static PyObject* psutil_proc_tty_nr(PyObject* self, PyObject* args);
static PyObject* psutil_proc_uids(PyObject* self, PyObject* args);
// --- system-related functions
static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_pids(PyObject* self, PyObject* args);
static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
static PyObject* psutil_users(PyObject* self, PyObject* args);
static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);

Просмотреть файл

@ -11,40 +11,143 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <ifaddrs.h> #include <sys/ioctl.h>
#include <net/if.h>
#ifdef __linux #ifdef PSUTIL_SUNOS10
#include <netdb.h> #include "arch/solaris/v10/ifaddrs.h"
#include <linux/if_packet.h> #elif PSUTIL_AIX
#endif // end linux #include "arch/aix/ifaddrs.h"
#else
#if defined(__FreeBSD__) || defined(__APPLE__) #include <ifaddrs.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if_dl.h>
#endif #endif
#if defined(__sun) #if defined(PSUTIL_LINUX)
#include <netdb.h> #include <netdb.h>
#include <linux/types.h>
#include <linux/if_packet.h>
#elif defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
#include <netdb.h>
#include <netinet/in.h>
#include <net/if_dl.h>
#include <sys/sockio.h>
#include <net/if_media.h>
#include <net/if.h>
#elif defined(PSUTIL_SUNOS)
#include <netdb.h>
#include <sys/sockio.h>
#elif defined(PSUTIL_AIX)
#include <netdb.h>
#endif #endif
#include "_psutil_posix.h" #include "_psutil_common.h"
/*
* Check if PID exists. Return values:
* 1: exists
* 0: does not exist
* -1: error (Python exception is set)
*/
int
psutil_pid_exists(long pid) {
int ret;
// No negative PID exists, plus -1 is an alias for sending signal
// too all processes except system ones. Not what we want.
if (pid < 0)
return 0;
// As per "man 2 kill" PID 0 is an alias for sending the signal to
// every process in the process group of the calling process.
// Not what we want. Some platforms have PID 0, some do not.
// We decide that at runtime.
if (pid == 0) {
#if defined(PSUTIL_LINUX) || defined(PSUTIL_FREEBSD)
return 0;
#else
return 1;
#endif
}
#if defined(PSUTIL_OSX)
ret = kill((pid_t)pid , 0);
#else
ret = kill(pid , 0);
#endif
if (ret == 0)
return 1;
else {
if (errno == ESRCH) {
// ESRCH == No such process
return 0;
}
else if (errno == EPERM) {
// EPERM clearly indicates there's a process to deny
// access to.
return 1;
}
else {
// According to "man 2 kill" possible error values are
// (EINVAL, EPERM, ESRCH) therefore we should never get
// here. If we do let's be explicit in considering this
// an error.
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
}
}
/*
* Utility used for those syscalls which do not return a meaningful
* error that we can translate into an exception which makes sense.
* As such, we'll have to guess.
* On UNIX, if errno is set, we return that one (OSError).
* Else, if PID does not exist we assume the syscall failed because
* of that so we raise NoSuchProcess.
* If none of this is true we giveup and raise RuntimeError(msg).
* This will always set a Python exception and return NULL.
*/
int
psutil_raise_for_pid(long pid, char *syscall_name) {
// Set exception to AccessDenied if pid exists else NoSuchProcess.
if (errno != 0) {
// Unlikely we get here.
PyErr_SetFromErrno(PyExc_OSError);
return 0;
}
else if (psutil_pid_exists(pid) == 0) {
psutil_debug("%s syscall failed and PID %i no longer exists; "
"assume NoSuchProcess", syscall_name, pid);
NoSuchProcess("");
}
else {
PyErr_Format(PyExc_RuntimeError, "%s syscall failed", syscall_name);
}
return 0;
}
/* /*
* Given a PID return process priority as a Python integer. * Given a PID return process priority as a Python integer.
*/ */
static PyObject * static PyObject *
psutil_posix_getpriority(PyObject *self, PyObject *args) psutil_posix_getpriority(PyObject *self, PyObject *args) {
{
long pid; long pid;
int priority; int priority;
errno = 0; errno = 0;
if (! PyArg_ParseTuple(args, "l", &pid)) if (! PyArg_ParseTuple(args, "l", &pid))
return NULL; return NULL;
#ifdef PSUTIL_OSX
priority = getpriority(PRIO_PROCESS, (id_t)pid);
#else
priority = getpriority(PRIO_PROCESS, pid); priority = getpriority(PRIO_PROCESS, pid);
#endif
if (errno != 0) if (errno != 0)
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
return Py_BuildValue("i", priority); return Py_BuildValue("i", priority);
@ -55,15 +158,19 @@ psutil_posix_getpriority(PyObject *self, PyObject *args)
* Given a PID and a value change process priority. * Given a PID and a value change process priority.
*/ */
static PyObject * static PyObject *
psutil_posix_setpriority(PyObject *self, PyObject *args) psutil_posix_setpriority(PyObject *self, PyObject *args) {
{
long pid; long pid;
int priority; int priority;
int retval; int retval;
if (! PyArg_ParseTuple(args, "li", &pid, &priority)) if (! PyArg_ParseTuple(args, "li", &pid, &priority))
return NULL; return NULL;
#ifdef PSUTIL_OSX
retval = setpriority(PRIO_PROCESS, (id_t)pid, priority);
#else
retval = setpriority(PRIO_PROCESS, pid, priority); retval = setpriority(PRIO_PROCESS, pid, priority);
#endif
if (retval == -1) if (retval == -1)
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
Py_RETURN_NONE; Py_RETURN_NONE;
@ -75,12 +182,11 @@ psutil_posix_setpriority(PyObject *self, PyObject *args)
* Return None if address family is not AF_INET* or AF_PACKET. * Return None if address family is not AF_INET* or AF_PACKET.
*/ */
static PyObject * static PyObject *
psutil_convert_ipaddr(struct sockaddr *addr, int family) psutil_convert_ipaddr(struct sockaddr *addr, int family) {
{
char buf[NI_MAXHOST]; char buf[NI_MAXHOST];
int err; int err;
int addrlen; int addrlen;
int n; size_t n;
size_t len; size_t len;
const char *data; const char *data;
char *ptr; char *ptr;
@ -109,14 +215,13 @@ psutil_convert_ipaddr(struct sockaddr *addr, int family)
return Py_BuildValue("s", buf); return Py_BuildValue("s", buf);
} }
} }
#ifdef __linux #ifdef PSUTIL_LINUX
else if (family == AF_PACKET) { else if (family == AF_PACKET) {
struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr; struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
len = lladdr->sll_halen; len = lladdr->sll_halen;
data = (const char *)lladdr->sll_addr; data = (const char *)lladdr->sll_addr;
} }
#endif #elif defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
#if defined(__FreeBSD__) || defined(__APPLE__)
else if (addr->sa_family == AF_LINK) { else if (addr->sa_family == AF_LINK) {
// Note: prior to Python 3.4 socket module does not expose // Note: prior to Python 3.4 socket module does not expose
// AF_LINK so we'll do. // AF_LINK so we'll do.
@ -153,8 +258,7 @@ psutil_convert_ipaddr(struct sockaddr *addr, int family)
* TODO: on Solaris we won't get any MAC address. * TODO: on Solaris we won't get any MAC address.
*/ */
static PyObject* static PyObject*
psutil_net_if_addrs(PyObject* self, PyObject* args) psutil_net_if_addrs(PyObject* self, PyObject* args) {
{
struct ifaddrs *ifaddr, *ifa; struct ifaddrs *ifaddr, *ifa;
int family; int family;
@ -163,6 +267,7 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
PyObject *py_address = NULL; PyObject *py_address = NULL;
PyObject *py_netmask = NULL; PyObject *py_netmask = NULL;
PyObject *py_broadcast = NULL; PyObject *py_broadcast = NULL;
PyObject *py_ptp = NULL;
if (py_retlist == NULL) if (py_retlist == NULL)
return NULL; return NULL;
@ -185,20 +290,34 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family); py_netmask = psutil_convert_ipaddr(ifa->ifa_netmask, family);
if (py_netmask == NULL) if (py_netmask == NULL)
goto error; goto error;
#ifdef __linux
py_broadcast = psutil_convert_ipaddr(ifa->ifa_ifu.ifu_broadaddr, family); if (ifa->ifa_flags & IFF_BROADCAST) {
#else py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family);
py_broadcast = psutil_convert_ipaddr(ifa->ifa_broadaddr, family); Py_INCREF(Py_None);
#endif py_ptp = Py_None;
if (py_broadcast == NULL) }
else if (ifa->ifa_flags & IFF_POINTOPOINT) {
py_ptp = psutil_convert_ipaddr(ifa->ifa_dstaddr, family);
Py_INCREF(Py_None);
py_broadcast = Py_None;
}
else {
Py_INCREF(Py_None);
Py_INCREF(Py_None);
py_broadcast = Py_None;
py_ptp = Py_None;
}
if ((py_broadcast == NULL) || (py_ptp == NULL))
goto error; goto error;
py_tuple = Py_BuildValue( py_tuple = Py_BuildValue(
"(siOOO)", "(siOOOO)",
ifa->ifa_name, ifa->ifa_name,
family, family,
py_address, py_address,
py_netmask, py_netmask,
py_broadcast py_broadcast,
py_ptp
); );
if (! py_tuple) if (! py_tuple)
@ -209,6 +328,7 @@ psutil_net_if_addrs(PyObject* self, PyObject* args)
Py_DECREF(py_address); Py_DECREF(py_address);
Py_DECREF(py_netmask); Py_DECREF(py_netmask);
Py_DECREF(py_broadcast); Py_DECREF(py_broadcast);
Py_DECREF(py_ptp);
} }
freeifaddrs(ifaddr); freeifaddrs(ifaddr);
@ -222,19 +342,98 @@ error:
Py_XDECREF(py_address); Py_XDECREF(py_address);
Py_XDECREF(py_netmask); Py_XDECREF(py_netmask);
Py_XDECREF(py_broadcast); Py_XDECREF(py_broadcast);
Py_XDECREF(py_ptp);
return NULL; return NULL;
} }
/* /*
* net_if_stats() implementation. This is here because it is common * Return NIC MTU. References:
* to both OSX and FreeBSD and I didn't know where else to put it. * http://www.i-scream.org/libstatgrab/
*/ */
#if defined(__FreeBSD__) || defined(__APPLE__) static PyObject *
psutil_net_if_mtu(PyObject *self, PyObject *args) {
char *nic_name;
int sock = 0;
int ret;
#ifdef PSUTIL_SUNOS10
struct lifreq lifr;
#else
struct ifreq ifr;
#endif
#include <sys/sockio.h> if (! PyArg_ParseTuple(args, "s", &nic_name))
#include <net/if_media.h> return NULL;
#include <net/if.h>
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
goto error;
#ifdef PSUTIL_SUNOS10
strncpy(lifr.lifr_name, nic_name, sizeof(lifr.lifr_name));
ret = ioctl(sock, SIOCGIFMTU, &lifr);
#else
strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
ret = ioctl(sock, SIOCGIFMTU, &ifr);
#endif
if (ret == -1)
goto error;
close(sock);
#ifdef PSUTIL_SUNOS10
return Py_BuildValue("i", lifr.lifr_mtu);
#else
return Py_BuildValue("i", ifr.ifr_mtu);
#endif
error:
if (sock != 0)
close(sock);
return PyErr_SetFromErrno(PyExc_OSError);
}
/*
* Inspect NIC flags, returns a bool indicating whether the NIC is
* running. References:
* http://www.i-scream.org/libstatgrab/
*/
static PyObject *
psutil_net_if_flags(PyObject *self, PyObject *args) {
char *nic_name;
int sock = 0;
int ret;
struct ifreq ifr;
if (! PyArg_ParseTuple(args, "s", &nic_name))
return NULL;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
goto error;
strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
if (ret == -1)
goto error;
close(sock);
if ((ifr.ifr_flags & IFF_UP) != 0)
return Py_BuildValue("O", Py_True);
else
return Py_BuildValue("O", Py_False);
error:
if (sock != 0)
close(sock);
return PyErr_SetFromErrno(PyExc_OSError);
}
/*
* net_if_stats() OSX/BSD implementation.
*/
#if defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
int psutil_get_nic_speed(int ifm_active) { int psutil_get_nic_speed(int ifm_active) {
// Determine NIC speed. Taken from: // Determine NIC speed. Taken from:
@ -267,8 +466,8 @@ int psutil_get_nic_speed(int ifm_active) {
case(IFM_1000_SX): // 1000BaseSX - multi-mode fiber case(IFM_1000_SX): // 1000BaseSX - multi-mode fiber
case(IFM_1000_LX): // 1000baseLX - single-mode fiber case(IFM_1000_LX): // 1000baseLX - single-mode fiber
case(IFM_1000_CX): // 1000baseCX - 150ohm STP case(IFM_1000_CX): // 1000baseCX - 150ohm STP
#if defined(IFM_1000_TX) && !defined(OPENBSD) #if defined(IFM_1000_TX) && !defined(PSUTIL_OPENBSD)
// FreeBSD 4 and others (but NOT OpenBSD)? // FreeBSD 4 and others (but NOT OpenBSD) -> #define IFM_1000_T in net/if_media.h
case(IFM_1000_TX): case(IFM_1000_TX):
#endif #endif
#ifdef IFM_1000_FX #ifdef IFM_1000_FX
@ -378,19 +577,15 @@ int psutil_get_nic_speed(int ifm_active) {
* http://www.i-scream.org/libstatgrab/ * http://www.i-scream.org/libstatgrab/
*/ */
static PyObject * static PyObject *
psutil_net_if_stats(PyObject *self, PyObject *args) psutil_net_if_duplex_speed(PyObject *self, PyObject *args) {
{
char *nic_name; char *nic_name;
int sock = 0; int sock = 0;
int ret; int ret;
int duplex; int duplex;
int speed; int speed;
int mtu;
struct ifreq ifr; struct ifreq ifr;
struct ifmediareq ifmed; struct ifmediareq ifmed;
PyObject *py_is_up = NULL;
if (! PyArg_ParseTuple(args, "s", &nic_name)) if (! PyArg_ParseTuple(args, "s", &nic_name))
return NULL; return NULL;
@ -399,22 +594,6 @@ psutil_net_if_stats(PyObject *self, PyObject *args)
goto error; goto error;
strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));
// is up?
ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
if (ret == -1)
goto error;
if ((ifr.ifr_flags & IFF_UP) != 0)
py_is_up = Py_True;
else
py_is_up = Py_False;
Py_INCREF(py_is_up);
// MTU
ret = ioctl(sock, SIOCGIFMTU, &ifr);
if (ret == -1)
goto error;
mtu = ifr.ifr_mtu;
// speed / duplex // speed / duplex
memset(&ifmed, 0, sizeof(struct ifmediareq)); memset(&ifmed, 0, sizeof(struct ifmediareq));
strlcpy(ifmed.ifm_name, nic_name, sizeof(ifmed.ifm_name)); strlcpy(ifmed.ifm_name, nic_name, sizeof(ifmed.ifm_name));
@ -434,34 +613,33 @@ psutil_net_if_stats(PyObject *self, PyObject *args)
} }
close(sock); close(sock);
Py_DECREF(py_is_up); return Py_BuildValue("[ii]", duplex, speed);
return Py_BuildValue("[Oiii]", py_is_up, duplex, speed, mtu);
error: error:
Py_XDECREF(py_is_up);
if (sock != 0) if (sock != 0)
close(sock); close(sock);
PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
return NULL;
} }
#endif // net_if_stats() implementation #endif // net_if_stats() OSX/BSD implementation
/* /*
* define the psutil C module methods and initialize the module. * define the psutil C module methods and initialize the module.
*/ */
static PyMethodDef static PyMethodDef
PsutilMethods[] = PsutilMethods[] = {
{
{"getpriority", psutil_posix_getpriority, METH_VARARGS, {"getpriority", psutil_posix_getpriority, METH_VARARGS,
"Return process priority"}, "Return process priority"},
{"setpriority", psutil_posix_setpriority, METH_VARARGS, {"setpriority", psutil_posix_setpriority, METH_VARARGS,
"Set process priority"}, "Set process priority"},
{"net_if_addrs", psutil_net_if_addrs, METH_VARARGS, {"net_if_addrs", psutil_net_if_addrs, METH_VARARGS,
"Retrieve NICs information"}, "Retrieve NICs information"},
#if defined(__FreeBSD__) || defined(__APPLE__) {"net_if_mtu", psutil_net_if_mtu, METH_VARARGS,
{"net_if_stats", psutil_net_if_stats, METH_VARARGS, "Retrieve NIC MTU"},
{"net_if_flags", psutil_net_if_flags, METH_VARARGS,
"Retrieve NIC flags"},
#if defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
{"net_if_duplex_speed", psutil_net_if_duplex_speed, METH_VARARGS,
"Return NIC stats."}, "Return NIC stats."},
#endif #endif
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
@ -485,6 +663,7 @@ psutil_posix_traverse(PyObject *m, visitproc visit, void *arg) {
return 0; return 0;
} }
static int static int
psutil_posix_clear(PyObject *m) { psutil_posix_clear(PyObject *m) {
Py_CLEAR(GETSTATE(m)->error); Py_CLEAR(GETSTATE(m)->error);
@ -519,7 +698,7 @@ void init_psutil_posix(void)
PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods); PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods);
#endif #endif
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__sun) #if defined(PSUTIL_BSD) || defined(PSUTIL_OSX) || defined(PSUTIL_SUNOS) || defined(PSUTIL_AIX)
PyModule_AddIntConstant(module, "AF_LINK", AF_LINK); PyModule_AddIntConstant(module, "AF_LINK", AF_LINK);
#endif #endif

Просмотреть файл

@ -4,12 +4,5 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
#include <Python.h> int psutil_pid_exists(long pid);
void psutil_raise_for_pid(long pid, char *msg);
static PyObject* psutil_net_if_addrs(PyObject* self, PyObject* args);
static PyObject* psutil_posix_getpriority(PyObject* self, PyObject* args);
static PyObject* psutil_posix_setpriority(PyObject* self, PyObject* args);
#if defined(__FreeBSD__) || defined(__APPLE__)
static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,28 +0,0 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
// processes
static PyObject* psutil_proc_basic_info(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cred(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
static PyObject* psutil_proc_name_and_args(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_ctx_switches(PyObject* self, PyObject* args);
static PyObject* psutil_proc_query_thread(PyObject* self, PyObject* args);
// system
static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
static PyObject* psutil_users(PyObject* self, PyObject* args);
static PyObject* psutil_net_connections(PyObject* self, PyObject* args);
static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,68 +0,0 @@
/*
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
#include <windows.h>
// --- per-process functions
static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
static PyObject* psutil_proc_info(PyObject* self, PyObject* args);
static PyObject* psutil_proc_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_proc_is_suspended(PyObject* self, PyObject* args);
static PyObject* psutil_proc_kill(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_info_2(PyObject* self, PyObject* args);
static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
static PyObject* psutil_proc_num_handles(PyObject* self, PyObject* args);
static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
static PyObject* psutil_proc_priority_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_priority_set(PyObject* self, PyObject* args);
static PyObject* psutil_proc_resume(PyObject* self, PyObject* args);
static PyObject* psutil_proc_suspend(PyObject* self, PyObject* args);
static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
static PyObject* psutil_proc_username(PyObject* self, PyObject* args);
static PyObject* psutil_proc_wait(PyObject* self, PyObject* args);
#if (PSUTIL_WINVER >= 0x0600) // Windows Vista
static PyObject* psutil_proc_io_priority_get(PyObject* self, PyObject* args);
static PyObject* psutil_proc_io_priority_set(PyObject* self, PyObject* args);
#endif
// --- system-related functions
static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
static PyObject* psutil_disk_usage(PyObject* self, PyObject* args);
static PyObject* psutil_net_connections(PyObject* self, PyObject* args);
static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
static PyObject* psutil_pid_exists(PyObject* self, PyObject* args);
static PyObject* psutil_pids(PyObject* self, PyObject* args);
static PyObject* psutil_ppid_map(PyObject* self, PyObject* args);
static PyObject* psutil_users(PyObject* self, PyObject* args);
static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
static PyObject* psutil_net_if_addrs(PyObject* self, PyObject* args);
static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args);
// --- windows API bindings
static PyObject* psutil_win32_QueryDosDevice(PyObject* self, PyObject* args);
// --- internal
int psutil_proc_suspend_or_resume(DWORD pid, int suspend);

679
third_party/python/psutil/psutil/_pswindows.py поставляемый
Просмотреть файл

@ -1,11 +1,10 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
"""Windows platform implementation.""" """Windows platform implementation."""
import contextlib
import errno import errno
import functools import functools
import os import os
@ -13,16 +12,49 @@ import sys
from collections import namedtuple from collections import namedtuple
from . import _common from . import _common
from . import _psutil_windows as cext try:
from ._common import conn_tmap, usage_percent, isfile_strict from . import _psutil_windows as cext
from ._common import sockfam_to_enum, socktype_to_enum except ImportError as err:
from ._compat import PY3, xrange, lru_cache, long if str(err).lower().startswith("dll load failed") and \
from ._psutil_windows import (ABOVE_NORMAL_PRIORITY_CLASS, sys.getwindowsversion()[0] < 6:
BELOW_NORMAL_PRIORITY_CLASS, # We may get here if:
HIGH_PRIORITY_CLASS, # 1) we are on an old Windows version
IDLE_PRIORITY_CLASS, # 2) psutil was installed via pip + wheel
NORMAL_PRIORITY_CLASS, # See: https://github.com/giampaolo/psutil/issues/811
REALTIME_PRIORITY_CLASS) # It must be noted that psutil can still (kind of) work
# on outdated systems if compiled / installed from sources,
# but if we get here it means this this was a wheel (or exe).
msg = "this Windows version is too old (< Windows Vista); "
msg += "psutil 3.4.2 is the latest version which supports Windows "
msg += "2000, XP and 2003 server; it may be possible that psutil "
msg += "will work if compiled from sources though"
raise RuntimeError(msg)
else:
raise
from ._common import conn_tmap
from ._common import ENCODING
from ._common import ENCODING_ERRS
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import long
from ._compat import lru_cache
from ._compat import PY3
from ._compat import unicode
from ._compat import xrange
from ._exceptions import AccessDenied
from ._exceptions import NoSuchProcess
from ._exceptions import TimeoutExpired
from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS
from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS
from ._psutil_windows import HIGH_PRIORITY_CLASS
from ._psutil_windows import IDLE_PRIORITY_CLASS
from ._psutil_windows import NORMAL_PRIORITY_CLASS
from ._psutil_windows import REALTIME_PRIORITY_CLASS
if sys.version_info >= (3, 4): if sys.version_info >= (3, 4):
import enum import enum
@ -31,19 +63,28 @@ else:
# process priority constants, import from __init__.py: # process priority constants, import from __init__.py:
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx # http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS", __extra__all__ = [
"HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS", "win_service_iter", "win_service_get",
"NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS", "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
"CONN_DELETE_TCB", "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
"AF_LINK", "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
] "CONN_DELETE_TCB",
"AF_LINK",
]
# --- module level constants (gets pushed up to psutil module)
# =====================================================================
# --- globals
# =====================================================================
CONN_DELETE_TCB = "DELETE_TCB" CONN_DELETE_TCB = "DELETE_TCB"
WAIT_TIMEOUT = 0x00000102 # 258 in decimal WAIT_TIMEOUT = 0x00000102 # 258 in decimal
ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES, ACCESS_DENIED_ERRSET = frozenset([errno.EPERM, errno.EACCES,
cext.ERROR_ACCESS_DENIED]) cext.ERROR_ACCESS_DENIED])
NO_SUCH_SERVICE_ERRSET = frozenset([cext.ERROR_INVALID_NAME,
cext.ERROR_SERVICE_DOES_NOT_EXIST])
if enum is None: if enum is None:
AF_LINK = -1 AF_LINK = -1
else: else:
@ -77,43 +118,94 @@ if enum is not None:
globals().update(Priority.__members__) globals().update(Priority.__members__)
scputimes = namedtuple('scputimes', ['user', 'system', 'idle']) pinfo_map = dict(
num_handles=0,
ctx_switches=1,
user_time=2,
kernel_time=3,
create_time=4,
num_threads=5,
io_rcount=6,
io_wcount=7,
io_rbytes=8,
io_wbytes=9,
io_count_others=10,
io_bytes_others=11,
num_page_faults=12,
peak_wset=13,
wset=14,
peak_paged_pool=15,
paged_pool=16,
peak_non_paged_pool=17,
non_paged_pool=18,
pagefile=19,
peak_pagefile=20,
mem_private=21,
)
# =====================================================================
# --- named tuples
# =====================================================================
# psutil.cpu_times()
scputimes = namedtuple('scputimes',
['user', 'system', 'idle', 'interrupt', 'dpc'])
# psutil.virtual_memory()
svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free']) svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
pextmem = namedtuple( # psutil.Process.memory_info()
'pextmem', ['num_page_faults', 'peak_wset', 'wset', 'peak_paged_pool', pmem = namedtuple(
'paged_pool', 'peak_nonpaged_pool', 'nonpaged_pool', 'pmem', ['rss', 'vms',
'pagefile', 'peak_pagefile', 'private']) 'num_page_faults', 'peak_wset', 'wset', 'peak_paged_pool',
'paged_pool', 'peak_nonpaged_pool', 'nonpaged_pool',
'pagefile', 'peak_pagefile', 'private'])
# psutil.Process.memory_full_info()
pfullmem = namedtuple('pfullmem', pmem._fields + ('uss', ))
# psutil.Process.memory_maps(grouped=True)
pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss']) pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss'])
# psutil.Process.memory_maps(grouped=False)
pmmap_ext = namedtuple( pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields)) 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
ntpinfo = namedtuple( # psutil.Process.io_counters()
'ntpinfo', ['num_handles', 'ctx_switches', 'user_time', 'kernel_time', pio = namedtuple('pio', ['read_count', 'write_count',
'create_time', 'num_threads', 'io_rcount', 'io_wcount', 'read_bytes', 'write_bytes',
'io_rbytes', 'io_wbytes']) 'other_count', 'other_bytes'])
# set later from __init__.py
NoSuchProcess = None # =====================================================================
AccessDenied = None # --- utils
TimeoutExpired = None # =====================================================================
@lru_cache(maxsize=512) @lru_cache(maxsize=512)
def _win32_QueryDosDevice(s): def convert_dos_path(s):
return cext.win32_QueryDosDevice(s) r"""Convert paths using native DOS format like:
"\Device\HarddiskVolume1\Windows\systemew\file.txt"
into:
def _convert_raw_path(s): "C:\Windows\systemew\file.txt"
# convert paths using native DOS format like: """
# "\Device\HarddiskVolume1\Windows\systemew\file.txt"
# into: "C:\Windows\systemew\file.txt"
if PY3 and not isinstance(s, str):
s = s.decode('utf8')
rawdrive = '\\'.join(s.split('\\')[:3]) rawdrive = '\\'.join(s.split('\\')[:3])
driveletter = _win32_QueryDosDevice(rawdrive) driveletter = cext.win32_QueryDosDevice(rawdrive)
return os.path.join(driveletter, s[len(rawdrive):]) return os.path.join(driveletter, s[len(rawdrive):])
# --- public functions def py2_strencode(s):
"""Encode a unicode string to a byte string by using the default fs
encoding + "replace" error handler.
"""
if PY3:
return s
else:
if isinstance(s, str):
return s
else:
return s.encode(ENCODING, errors=ENCODING_ERRS)
# =====================================================================
# --- memory
# =====================================================================
def virtual_memory(): def virtual_memory():
@ -139,15 +231,21 @@ def swap_memory():
return _common.sswap(total, used, free, percent, 0, 0) return _common.sswap(total, used, free, percent, 0, 0)
# =====================================================================
# --- disk
# =====================================================================
disk_io_counters = cext.disk_io_counters
def disk_usage(path): def disk_usage(path):
"""Return disk usage associated with path.""" """Return disk usage associated with path."""
try: if PY3 and isinstance(path, bytes):
total, free = cext.disk_usage(path) # XXX: do we want to use "strict"? Probably yes, in order
except WindowsError: # to fail immediately. After all we are accepting input here...
if not os.path.exists(path): path = path.decode(ENCODING, errors="strict")
msg = "No such file or directory: '%s'" % path total, free = cext.disk_usage(path)
raise OSError(errno.ENOENT, msg)
raise
used = total - free used = total - free
percent = usage_percent(used, total, _round=1) percent = usage_percent(used, total, _round=1)
return _common.sdiskusage(total, used, free, percent) return _common.sdiskusage(total, used, free, percent)
@ -159,18 +257,27 @@ def disk_partitions(all):
return [_common.sdiskpart(*x) for x in rawlist] return [_common.sdiskpart(*x) for x in rawlist]
# =====================================================================
# --- CPU
# =====================================================================
def cpu_times(): def cpu_times():
"""Return system CPU times as a named tuple.""" """Return system CPU times as a named tuple."""
user, system, idle = cext.cpu_times() user, system, idle = cext.cpu_times()
return scputimes(user, system, idle) # Internally, GetSystemTimes() is used, and it doesn't return
# interrupt and dpc times. cext.per_cpu_times() does, so we
# rely on it to get those only.
percpu_summed = scputimes(*[sum(n) for n in zip(*cext.per_cpu_times())])
return scputimes(user, system, idle,
percpu_summed.interrupt, percpu_summed.dpc)
def per_cpu_times(): def per_cpu_times():
"""Return system per-CPU times as a list of named tuples.""" """Return system per-CPU times as a list of named tuples."""
ret = [] ret = []
for cpu_t in cext.per_cpu_times(): for user, system, idle, interrupt, dpc in cext.per_cpu_times():
user, system, idle = cpu_t item = scputimes(user, system, idle, interrupt, dpc)
item = scputimes(user, system, idle)
ret.append(item) ret.append(item)
return ret return ret
@ -185,9 +292,26 @@ def cpu_count_physical():
return cext.cpu_count_phys() return cext.cpu_count_phys()
def boot_time(): def cpu_stats():
"""The system boot time expressed in seconds since the epoch.""" """Return CPU statistics."""
return cext.boot_time() ctx_switches, interrupts, dpcs, syscalls = cext.cpu_stats()
soft_interrupts = 0
return _common.scpustats(ctx_switches, interrupts, soft_interrupts,
syscalls)
def cpu_freq():
"""Return CPU frequency.
On Windows per-cpu frequency is not supported.
"""
curr, max_ = cext.cpu_freq()
min_ = 0.0
return [_common.scpufreq(float(curr), min_, float(max_))]
# =====================================================================
# --- network
# =====================================================================
def net_connections(kind, _pid=-1): def net_connections(kind, _pid=-1):
@ -202,6 +326,10 @@ def net_connections(kind, _pid=-1):
ret = set() ret = set()
for item in rawlist: for item in rawlist:
fd, fam, type, laddr, raddr, status, pid = item fd, fam, type, laddr, raddr, status, pid = item
if laddr:
laddr = _common.addr(*laddr)
if raddr:
raddr = _common.addr(*raddr)
status = TCP_STATUSES[status] status = TCP_STATUSES[status]
fam = sockfam_to_enum(fam) fam = sockfam_to_enum(fam)
type = socktype_to_enum(type) type = socktype_to_enum(type)
@ -214,8 +342,13 @@ def net_connections(kind, _pid=-1):
def net_if_stats(): def net_if_stats():
ret = cext.net_if_stats() """Get NIC stats (isup, duplex, speed, mtu)."""
for name, items in ret.items(): ret = {}
rawdict = cext.net_if_stats()
for name, items in rawdict.items():
if not PY3:
assert isinstance(name, unicode), type(name)
name = py2_strencode(name)
isup, duplex, speed, mtu = items isup, duplex, speed, mtu = items
if hasattr(_common, 'NicDuplex'): if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex) duplex = _common.NicDuplex(duplex)
@ -223,23 +356,273 @@ def net_if_stats():
return ret return ret
def net_io_counters():
"""Return network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
"""
ret = cext.net_io_counters()
return dict([(py2_strencode(k), v) for k, v in ret.items()])
def net_if_addrs():
"""Return the addresses associated to each NIC."""
ret = []
for items in cext.net_if_addrs():
items = list(items)
items[0] = py2_strencode(items[0])
ret.append(items)
return ret
# =====================================================================
# --- sensors
# =====================================================================
def sensors_battery():
"""Return battery information."""
# For constants meaning see:
# https://msdn.microsoft.com/en-us/library/windows/desktop/
# aa373232(v=vs.85).aspx
acline_status, flags, percent, secsleft = cext.sensors_battery()
power_plugged = acline_status == 1
no_battery = bool(flags & 128)
charging = bool(flags & 8)
if no_battery:
return None
if power_plugged or charging:
secsleft = _common.POWER_TIME_UNLIMITED
elif secsleft == -1:
secsleft = _common.POWER_TIME_UNKNOWN
return _common.sbattery(percent, secsleft, power_plugged)
# =====================================================================
# --- other system functions
# =====================================================================
_last_btime = 0
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
# This dirty hack is to adjust the precision of the returned
# value which may have a 1 second fluctuation, see:
# https://github.com/giampaolo/psutil/issues/1007
global _last_btime
ret = float(cext.boot_time())
if abs(ret - _last_btime) <= 1:
return _last_btime
else:
_last_btime = ret
return ret
def users(): def users():
"""Return currently connected users as a list of namedtuples.""" """Return currently connected users as a list of namedtuples."""
retlist = [] retlist = []
rawlist = cext.users() rawlist = cext.users()
for item in rawlist: for item in rawlist:
user, hostname, tstamp = item user, hostname, tstamp = item
nt = _common.suser(user, None, hostname, tstamp) user = py2_strencode(user)
nt = _common.suser(user, None, hostname, tstamp, None)
retlist.append(nt) retlist.append(nt)
return retlist return retlist
# =====================================================================
# --- Windows services
# =====================================================================
def win_service_iter():
"""Yields a list of WindowsService instances."""
for name, display_name in cext.winservice_enumerate():
yield WindowsService(py2_strencode(name), py2_strencode(display_name))
def win_service_get(name):
"""Open a Windows service and return it as a WindowsService instance."""
service = WindowsService(name, None)
service._display_name = service._query_config()['display_name']
return service
class WindowsService(object):
"""Represents an installed Windows service."""
def __init__(self, name, display_name):
self._name = name
self._display_name = display_name
def __str__(self):
details = "(name=%r, display_name=%r)" % (
self._name, self._display_name)
return "%s%s" % (self.__class__.__name__, details)
def __repr__(self):
return "<%s at %s>" % (self.__str__(), id(self))
def __eq__(self, other):
# Test for equality with another WindosService object based
# on name.
if not isinstance(other, WindowsService):
return NotImplemented
return self._name == other._name
def __ne__(self, other):
return not self == other
def _query_config(self):
with self._wrap_exceptions():
display_name, binpath, username, start_type = \
cext.winservice_query_config(self._name)
# XXX - update _self.display_name?
return dict(
display_name=py2_strencode(display_name),
binpath=py2_strencode(binpath),
username=py2_strencode(username),
start_type=py2_strencode(start_type))
def _query_status(self):
with self._wrap_exceptions():
status, pid = cext.winservice_query_status(self._name)
if pid == 0:
pid = None
return dict(status=status, pid=pid)
@contextlib.contextmanager
def _wrap_exceptions(self):
"""Ctx manager which translates bare OSError and WindowsError
exceptions into NoSuchProcess and AccessDenied.
"""
try:
yield
except WindowsError as err:
if err.errno in ACCESS_DENIED_ERRSET:
raise AccessDenied(
pid=None, name=self._name,
msg="service %r is not querable (not enough privileges)" %
self._name)
elif err.errno in NO_SUCH_SERVICE_ERRSET or \
err.winerror in NO_SUCH_SERVICE_ERRSET:
raise NoSuchProcess(
pid=None, name=self._name,
msg="service %r does not exist)" % self._name)
else:
raise
# config query
def name(self):
"""The service name. This string is how a service is referenced
and can be passed to win_service_get() to get a new
WindowsService instance.
"""
return self._name
def display_name(self):
"""The service display name. The value is cached when this class
is instantiated.
"""
return self._display_name
def binpath(self):
"""The fully qualified path to the service binary/exe file as
a string, including command line arguments.
"""
return self._query_config()['binpath']
def username(self):
"""The name of the user that owns this service."""
return self._query_config()['username']
def start_type(self):
"""A string which can either be "automatic", "manual" or
"disabled".
"""
return self._query_config()['start_type']
# status query
def pid(self):
"""The process PID, if any, else None. This can be passed
to Process class to control the service's process.
"""
return self._query_status()['pid']
def status(self):
"""Service status as a string."""
return self._query_status()['status']
def description(self):
"""Service long description."""
return py2_strencode(cext.winservice_query_descr(self.name()))
# utils
def as_dict(self):
"""Utility method retrieving all the information above as a
dictionary.
"""
d = self._query_config()
d.update(self._query_status())
d['name'] = self.name()
d['display_name'] = self.display_name()
d['description'] = self.description()
return d
# actions
# XXX: the necessary C bindings for start() and stop() are
# implemented but for now I prefer not to expose them.
# I may change my mind in the future. Reasons:
# - they require Administrator privileges
# - can't implement a timeout for stop() (unless by using a thread,
# which sucks)
# - would require adding ServiceAlreadyStarted and
# ServiceAlreadyStopped exceptions, adding two new APIs.
# - we might also want to have modify(), which would basically mean
# rewriting win32serviceutil.ChangeServiceConfig, which involves a
# lot of stuff (and API constants which would pollute the API), see:
# http://pyxr.sourceforge.net/PyXR/c/python24/lib/site-packages/
# win32/lib/win32serviceutil.py.html#0175
# - psutil is typically about "read only" monitoring stuff;
# win_service_* APIs should only be used to retrieve a service and
# check whether it's running
# def start(self, timeout=None):
# with self._wrap_exceptions():
# cext.winservice_start(self.name())
# if timeout:
# giveup_at = time.time() + timeout
# while True:
# if self.status() == "running":
# return
# else:
# if time.time() > giveup_at:
# raise TimeoutExpired(timeout)
# else:
# time.sleep(.1)
# def stop(self):
# # Note: timeout is not implemented because it's just not
# # possible, see:
# # http://stackoverflow.com/questions/11973228/
# with self._wrap_exceptions():
# return cext.winservice_stop(self.name())
# =====================================================================
# --- processes
# =====================================================================
pids = cext.pids pids = cext.pids
pid_exists = cext.pid_exists pid_exists = cext.pid_exists
net_io_counters = cext.net_io_counters ppid_map = cext.ppid_map # used internally by Process.children()
disk_io_counters = cext.disk_io_counters
ppid_map = cext.ppid_map # not meant to be public
net_if_addrs = cext.net_if_addrs
def wrap_exceptions(fun): def wrap_exceptions(fun):
@ -251,10 +634,7 @@ def wrap_exceptions(fun):
try: try:
return fun(self, *args, **kwargs) return fun(self, *args, **kwargs)
except OSError as err: except OSError as err:
# support for private module import if err.errno in ACCESS_DENIED_ERRSET:
if NoSuchProcess is None or AccessDenied is None:
raise
if err.errno in ACCESS_DENIED_SET:
raise AccessDenied(self.pid, self._name) raise AccessDenied(self.pid, self._name)
if err.errno == errno.ESRCH: if err.errno == errno.ESRCH:
raise NoSuchProcess(self.pid, self._name) raise NoSuchProcess(self.pid, self._name)
@ -272,6 +652,23 @@ class Process(object):
self._name = None self._name = None
self._ppid = None self._ppid = None
# --- oneshot() stuff
def oneshot_enter(self):
self.oneshot_info.cache_activate()
def oneshot_exit(self):
self.oneshot_info.cache_deactivate()
@memoize_when_activated
def oneshot_info(self):
"""Return multiple information about this process as a
raw tuple.
"""
ret = cext.proc_info(self.pid)
assert len(ret) == len(pinfo_map)
return ret
@wrap_exceptions @wrap_exceptions
def name(self): def name(self):
"""Return process name, which on Windows is always the final """Return process name, which on Windows is always the final
@ -287,9 +684,9 @@ class Process(object):
try: try:
# Note: this will fail with AD for most PIDs owned # Note: this will fail with AD for most PIDs owned
# by another user but it's faster. # by another user but it's faster.
return os.path.basename(self.exe()) return py2_strencode(os.path.basename(self.exe()))
except AccessDenied: except AccessDenied:
return cext.proc_name(self.pid) return py2_strencode(cext.proc_name(self.pid))
@wrap_exceptions @wrap_exceptions
def exe(self): def exe(self):
@ -301,11 +698,22 @@ class Process(object):
# see https://github.com/giampaolo/psutil/issues/528 # see https://github.com/giampaolo/psutil/issues/528
if self.pid in (0, 4): if self.pid in (0, 4):
raise AccessDenied(self.pid, self._name) raise AccessDenied(self.pid, self._name)
return _convert_raw_path(cext.proc_exe(self.pid)) return py2_strencode(convert_dos_path(cext.proc_exe(self.pid)))
@wrap_exceptions @wrap_exceptions
def cmdline(self): def cmdline(self):
return cext.proc_cmdline(self.pid) ret = cext.proc_cmdline(self.pid)
if PY3:
return ret
else:
return [py2_strencode(s) for s in ret]
@wrap_exceptions
def environ(self):
ustr = cext.proc_environ(self.pid)
if ustr and not PY3:
assert isinstance(ustr, unicode), type(ustr)
return parse_environ_block(py2_strencode(ustr))
def ppid(self): def ppid(self):
try: try:
@ -317,24 +725,39 @@ class Process(object):
try: try:
return cext.proc_memory_info(self.pid) return cext.proc_memory_info(self.pid)
except OSError as err: except OSError as err:
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
# TODO: the C ext can probably be refactored in order # TODO: the C ext can probably be refactored in order
# to get this from cext.proc_info() # to get this from cext.proc_info()
return cext.proc_memory_info_2(self.pid) info = self.oneshot_info()
return (
info[pinfo_map['num_page_faults']],
info[pinfo_map['peak_wset']],
info[pinfo_map['wset']],
info[pinfo_map['peak_paged_pool']],
info[pinfo_map['paged_pool']],
info[pinfo_map['peak_non_paged_pool']],
info[pinfo_map['non_paged_pool']],
info[pinfo_map['pagefile']],
info[pinfo_map['peak_pagefile']],
info[pinfo_map['mem_private']],
)
raise raise
@wrap_exceptions @wrap_exceptions
def memory_info(self): def memory_info(self):
# on Windows RSS == WorkingSetSize and VSM == PagefileUsage # on Windows RSS == WorkingSetSize and VSM == PagefileUsage.
# fields of PROCESS_MEMORY_COUNTERS struct: # Underlying C function returns fields of PROCESS_MEMORY_COUNTERS
# http://msdn.microsoft.com/en-us/library/windows/desktop/ # struct.
# ms684877(v=vs.85).aspx
t = self._get_raw_meminfo() t = self._get_raw_meminfo()
return _common.pmem(t[2], t[7]) rss = t[2] # wset
vms = t[7] # pagefile
return pmem(*(rss, vms, ) + t)
@wrap_exceptions @wrap_exceptions
def memory_info_ex(self): def memory_full_info(self):
return pextmem(*self._get_raw_meminfo()) basic_mem = self.memory_info()
uss = cext.proc_memory_uss(self.pid)
return pfullmem(*basic_mem + (uss, ))
def memory_maps(self): def memory_maps(self):
try: try:
@ -342,14 +765,17 @@ class Process(object):
except OSError as err: except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're # XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring. # returning a generator; probably needs refactoring.
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
raise AccessDenied(self.pid, self._name) raise AccessDenied(self.pid, self._name)
if err.errno == errno.ESRCH: if err.errno == errno.ESRCH:
raise NoSuchProcess(self.pid, self._name) raise NoSuchProcess(self.pid, self._name)
raise raise
else: else:
for addr, perm, path, rss in raw: for addr, perm, path, rss in raw:
path = _convert_raw_path(path) path = convert_dos_path(path)
if not PY3:
assert isinstance(path, unicode), type(path)
path = py2_strencode(path)
addr = hex(addr) addr = hex(addr)
yield (addr, perm, path, rss) yield (addr, perm, path, rss)
@ -357,26 +783,34 @@ class Process(object):
def kill(self): def kill(self):
return cext.proc_kill(self.pid) return cext.proc_kill(self.pid)
@wrap_exceptions
def send_signal(self, sig):
os.kill(self.pid, sig)
@wrap_exceptions @wrap_exceptions
def wait(self, timeout=None): def wait(self, timeout=None):
if timeout is None: if timeout is None:
timeout = cext.INFINITE cext_timeout = cext.INFINITE
else: else:
# WaitForSingleObject() expects time in milliseconds # WaitForSingleObject() expects time in milliseconds
timeout = int(timeout * 1000) cext_timeout = int(timeout * 1000)
ret = cext.proc_wait(self.pid, timeout) while True:
if ret == WAIT_TIMEOUT: ret = cext.proc_wait(self.pid, cext_timeout)
# support for private module import if ret == WAIT_TIMEOUT:
if TimeoutExpired is None: raise TimeoutExpired(timeout, self.pid, self._name)
raise RuntimeError("timeout expired") if pid_exists(self.pid):
raise TimeoutExpired(timeout, self.pid, self._name) if timeout is None:
return ret continue
else:
raise TimeoutExpired(timeout, self.pid, self._name)
return ret
@wrap_exceptions @wrap_exceptions
def username(self): def username(self):
if self.pid in (0, 4): if self.pid in (0, 4):
return 'NT AUTHORITY\\SYSTEM' return 'NT AUTHORITY\\SYSTEM'
return cext.proc_username(self.pid) domain, user = cext.proc_username(self.pid)
return py2_strencode(domain) + '\\' + py2_strencode(user)
@wrap_exceptions @wrap_exceptions
def create_time(self): def create_time(self):
@ -386,13 +820,13 @@ class Process(object):
try: try:
return cext.proc_create_time(self.pid) return cext.proc_create_time(self.pid)
except OSError as err: except OSError as err:
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
return ntpinfo(*cext.proc_info(self.pid)).create_time return self.oneshot_info()[pinfo_map['create_time']]
raise raise
@wrap_exceptions @wrap_exceptions
def num_threads(self): def num_threads(self):
return ntpinfo(*cext.proc_info(self.pid)).num_threads return self.oneshot_info()[pinfo_map['num_threads']]
@wrap_exceptions @wrap_exceptions
def threads(self): def threads(self):
@ -406,14 +840,16 @@ class Process(object):
@wrap_exceptions @wrap_exceptions
def cpu_times(self): def cpu_times(self):
try: try:
ret = cext.proc_cpu_times(self.pid) user, system = cext.proc_cpu_times(self.pid)
except OSError as err: except OSError as err:
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
nt = ntpinfo(*cext.proc_info(self.pid)) info = self.oneshot_info()
ret = (nt.user_time, nt.kernel_time) user = info[pinfo_map['user_time']]
system = info[pinfo_map['kernel_time']]
else: else:
raise raise
return _common.pcputimes(*ret) # Children user/system times are not retrievable (set to 0).
return _common.pcputimes(user, system, 0.0, 0.0)
@wrap_exceptions @wrap_exceptions
def suspend(self): def suspend(self):
@ -430,24 +866,26 @@ class Process(object):
# return a normalized pathname since the native C function appends # return a normalized pathname since the native C function appends
# "\\" at the and of the path # "\\" at the and of the path
path = cext.proc_cwd(self.pid) path = cext.proc_cwd(self.pid)
return os.path.normpath(path) return py2_strencode(os.path.normpath(path))
@wrap_exceptions @wrap_exceptions
def open_files(self): def open_files(self):
if self.pid in (0, 4): if self.pid in (0, 4):
return [] return []
retlist = [] ret = set()
# Filenames come in in native format like: # Filenames come in in native format like:
# "\Device\HarddiskVolume1\Windows\systemew\file.txt" # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
# Convert the first part in the corresponding drive letter # Convert the first part in the corresponding drive letter
# (e.g. "C:\") by using Windows's QueryDosDevice() # (e.g. "C:\") by using Windows's QueryDosDevice()
raw_file_names = cext.proc_open_files(self.pid) raw_file_names = cext.proc_open_files(self.pid)
for _file in raw_file_names: for _file in raw_file_names:
_file = _convert_raw_path(_file) _file = convert_dos_path(_file)
if isfile_strict(_file) and _file not in retlist: if isfile_strict(_file):
if not PY3:
_file = py2_strencode(_file)
ntuple = _common.popenfile(_file, -1) ntuple = _common.popenfile(_file, -1)
retlist.append(ntuple) ret.add(ntuple)
return retlist return list(ret)
@wrap_exceptions @wrap_exceptions
def connections(self, kind='inet'): def connections(self, kind='inet'):
@ -485,12 +923,19 @@ class Process(object):
try: try:
ret = cext.proc_io_counters(self.pid) ret = cext.proc_io_counters(self.pid)
except OSError as err: except OSError as err:
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
nt = ntpinfo(*cext.proc_info(self.pid)) info = self.oneshot_info()
ret = (nt.io_rcount, nt.io_wcount, nt.io_rbytes, nt.io_wbytes) ret = (
info[pinfo_map['io_rcount']],
info[pinfo_map['io_wcount']],
info[pinfo_map['io_rbytes']],
info[pinfo_map['io_wbytes']],
info[pinfo_map['io_count_others']],
info[pinfo_map['io_bytes_others']],
)
else: else:
raise raise
return _common.pio(*ret) return pio(*ret)
@wrap_exceptions @wrap_exceptions
def status(self): def status(self):
@ -537,12 +982,12 @@ class Process(object):
try: try:
return cext.proc_num_handles(self.pid) return cext.proc_num_handles(self.pid)
except OSError as err: except OSError as err:
if err.errno in ACCESS_DENIED_SET: if err.errno in ACCESS_DENIED_ERRSET:
return ntpinfo(*cext.proc_info(self.pid)).num_handles return self.oneshot_info()[pinfo_map['num_handles']]
raise raise
@wrap_exceptions @wrap_exceptions
def num_ctx_switches(self): def num_ctx_switches(self):
ctx_switches = ntpinfo(*cext.proc_info(self.pid)).ctx_switches ctx_switches = self.oneshot_info()[pinfo_map['ctx_switches']]
# only voluntary ctx switches are supported # only voluntary ctx switches are supported
return _common.pctxsw(ctx_switches, 0) return _common.pctxsw(ctx_switches, 0)

79
third_party/python/psutil/psutil/arch/aix/common.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,79 @@
/*
* Copyright (c) 2017, Arnon Yaari
* 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 <sys/core.h>
#include <stdlib.h>
#include "common.h"
/* psutil_kread() - read from kernel memory */
int
psutil_kread(
int Kd, /* kernel memory file descriptor */
KA_T addr, /* kernel memory address */
char *buf, /* buffer to receive data */
size_t len) { /* length to read */
int br;
if (lseek64(Kd, (off64_t)addr, L_SET) == (off64_t)-1) {
PyErr_SetFromErrno(PyExc_OSError);
return 1;
}
br = read(Kd, buf, len);
if (br == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return 1;
}
if (br != len) {
PyErr_SetString(PyExc_RuntimeError,
"size mismatch when reading kernel memory fd");
return 1;
}
return 0;
}
struct procentry64 *
psutil_read_process_table(int * num) {
size_t msz;
pid32_t pid = 0;
struct procentry64 *processes = (struct procentry64 *)NULL;
struct procentry64 *p;
int Np = 0; /* number of processes allocated in 'processes' */
int np = 0; /* number of processes read into 'processes' */
int i; /* number of processes read in current iteration */
msz = (size_t)(PROCSIZE * PROCINFO_INCR);
processes = (struct procentry64 *)malloc(msz);
if (!processes) {
PyErr_NoMemory();
return NULL;
}
Np = PROCINFO_INCR;
p = processes;
while ((i = getprocs64(p, PROCSIZE, (struct fdsinfo64 *)NULL, 0, &pid,
PROCINFO_INCR))
== PROCINFO_INCR) {
np += PROCINFO_INCR;
if (np >= Np) {
msz = (size_t)(PROCSIZE * (Np + PROCINFO_INCR));
processes = (struct procentry64 *)realloc((char *)processes, msz);
if (!processes) {
PyErr_NoMemory();
return NULL;
}
Np += PROCINFO_INCR;
}
p = (struct procentry64 *)((char *)processes + (np * PROCSIZE));
}
/* add the number of processes read in the last iteration */
if (i > 0)
np += i;
*num = np;
return processes;
}

31
third_party/python/psutil/psutil/arch/aix/common.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef __PSUTIL_AIX_COMMON_H__
#define __PSUTIL_AIX_COMMON_H__
#include <sys/core.h>
#define PROCINFO_INCR (256)
#define PROCSIZE (sizeof(struct procentry64))
#define FDSINFOSIZE (sizeof(struct fdsinfo64))
#define KMEM "/dev/kmem"
typedef u_longlong_t KA_T;
/* psutil_kread() - read from kernel memory */
int psutil_kread(int Kd, /* kernel memory file descriptor */
KA_T addr, /* kernel memory address */
char *buf, /* buffer to receive data */
size_t len); /* length to read */
struct procentry64 *
psutil_read_process_table(
int * num /* out - number of processes read */
);
#endif /* __PSUTIL_AIX_COMMON_H__ */

149
third_party/python/psutil/psutil/arch/aix/ifaddrs.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,149 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*! Based on code from
https://lists.samba.org/archive/samba-technical/2009-February/063079.html
!*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "ifaddrs.h"
#define MAX(x,y) ((x)>(y)?(x):(y))
#define SIZE(p) MAX((p).sa_len,sizeof(p))
static struct sockaddr *
sa_dup(struct sockaddr *sa1)
{
struct sockaddr *sa2;
size_t sz = sa1->sa_len;
sa2 = (struct sockaddr *) calloc(1, sz);
if (sa2 == NULL)
return NULL;
memcpy(sa2, sa1, sz);
return sa2;
}
void freeifaddrs(struct ifaddrs *ifp)
{
if (NULL == ifp) return;
free(ifp->ifa_name);
free(ifp->ifa_addr);
free(ifp->ifa_netmask);
free(ifp->ifa_dstaddr);
freeifaddrs(ifp->ifa_next);
free(ifp);
}
int getifaddrs(struct ifaddrs **ifap)
{
int sd, ifsize;
char *ccp, *ecp;
struct ifconf ifc;
struct ifreq *ifr;
struct ifaddrs *cifa = NULL; /* current */
struct ifaddrs *pifa = NULL; /* previous */
const size_t IFREQSZ = sizeof(struct ifreq);
int fam;
*ifap = NULL;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == -1)
goto error;
/* find how much memory to allocate for the SIOCGIFCONF call */
if (ioctl(sd, SIOCGSIZIFCONF, (caddr_t)&ifsize) < 0)
goto error;
ifc.ifc_req = (struct ifreq *) calloc(1, ifsize);
if (ifc.ifc_req == NULL)
goto error;
ifc.ifc_len = ifsize;
if (ioctl(sd, SIOCGIFCONF, &ifc) < 0)
goto error;
ccp = (char *)ifc.ifc_req;
ecp = ccp + ifsize;
while (ccp < ecp) {
ifr = (struct ifreq *) ccp;
ifsize = sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr);
fam = ifr->ifr_addr.sa_family;
if (fam == AF_INET || fam == AF_INET6) {
cifa = (struct ifaddrs *) calloc(1, sizeof(struct ifaddrs));
if (cifa == NULL)
goto error;
cifa->ifa_next = NULL;
if (pifa == NULL) *ifap = cifa; /* first one */
else pifa->ifa_next = cifa;
cifa->ifa_name = strdup(ifr->ifr_name);
if (cifa->ifa_name == NULL)
goto error;
cifa->ifa_flags = 0;
cifa->ifa_dstaddr = NULL;
cifa->ifa_addr = sa_dup(&ifr->ifr_addr);
if (cifa->ifa_addr == NULL)
goto error;
if (fam == AF_INET) {
if (ioctl(sd, SIOCGIFNETMASK, ifr, IFREQSZ) < 0)
goto error;
cifa->ifa_netmask = sa_dup(&ifr->ifr_addr);
if (cifa->ifa_netmask == NULL)
goto error;
}
if (0 == ioctl(sd, SIOCGIFFLAGS, ifr)) /* optional */
cifa->ifa_flags = ifr->ifr_flags;
if (fam == AF_INET) {
if (ioctl(sd, SIOCGIFDSTADDR, ifr, IFREQSZ) < 0) {
if (0 == ioctl(sd, SIOCGIFBRDADDR, ifr, IFREQSZ)) {
cifa->ifa_dstaddr = sa_dup(&ifr->ifr_addr);
if (cifa->ifa_dstaddr == NULL)
goto error;
}
}
else {
cifa->ifa_dstaddr = sa_dup(&ifr->ifr_addr);
if (cifa->ifa_dstaddr == NULL)
goto error;
}
}
pifa = cifa;
}
ccp += ifsize;
}
free(ifc.ifc_req);
close(sd);
return 0;
error:
if (ifc.ifc_req != NULL)
free(ifc.ifc_req);
if (sd != -1)
close(sd);
freeifaddrs(*ifap);
return (-1);
}

35
third_party/python/psutil/psutil/arch/aix/ifaddrs.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,35 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*! Based on code from
https://lists.samba.org/archive/samba-technical/2009-February/063079.html
!*/
#ifndef GENERIC_AIX_IFADDRS_H
#define GENERIC_AIX_IFADDRS_H
#include <sys/socket.h>
#include <net/if.h>
#undef ifa_dstaddr
#undef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
};
extern int getifaddrs(struct ifaddrs **);
extern void freeifaddrs(struct ifaddrs *);
#endif

287
third_party/python/psutil/psutil/arch/aix/net_connections.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,287 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Baded on code from lsof:
* http://www.ibm.com/developerworks/aix/library/au-lsof.html
* - dialects/aix/dproc.c:gather_proc_info
* - lib/prfp.c:process_file
* - dialects/aix/dsock.c:process_socket
* - dialects/aix/dproc.c:get_kernel_access
*/
#include <Python.h>
#include <stdlib.h>
#include <fcntl.h>
#define _KERNEL
#include <sys/file.h>
#undef _KERNEL
#include <sys/types.h>
#include <sys/core.h>
#include <sys/domain.h>
#include <sys/un.h>
#include <netinet/in_pcb.h>
#include <arpa/inet.h>
#include "../../_psutil_common.h"
#include "net_kernel_structs.h"
#include "net_connections.h"
#include "common.h"
#define NO_SOCKET (PyObject *)(-1)
static int
read_unp_addr(
int Kd,
KA_T unp_addr,
char *buf,
size_t buflen
) {
struct sockaddr_un *ua = (struct sockaddr_un *)NULL;
struct sockaddr_un un;
struct mbuf64 mb;
int uo;
if (psutil_kread(Kd, unp_addr, (char *)&mb, sizeof(mb))) {
return 1;
}
uo = (int)(mb.m_hdr.mh_data - unp_addr);
if ((uo + sizeof(struct sockaddr)) <= sizeof(mb))
ua = (struct sockaddr_un *)((char *)&mb + uo);
else {
if (psutil_kread(Kd, (KA_T)mb.m_hdr.mh_data,
(char *)&un, sizeof(un))) {
return 1;
}
ua = &un;
}
if (ua && ua->sun_path[0]) {
if (mb.m_len > sizeof(struct sockaddr_un))
mb.m_len = sizeof(struct sockaddr_un);
*((char *)ua + mb.m_len - 1) = '\0';
snprintf(buf, buflen, "%s", ua->sun_path);
}
return 0;
}
static PyObject *
process_file(int Kd, pid32_t pid, int fd, KA_T fp) {
struct file64 f;
struct socket64 s;
struct protosw64 p;
struct domain d;
struct inpcb64 inp;
int fam;
struct tcpcb64 t;
int state = PSUTIL_CONN_NONE;
unsigned char *laddr = (unsigned char *)NULL;
unsigned char *raddr = (unsigned char *)NULL;
int rport, lport;
char laddr_str[INET6_ADDRSTRLEN];
char raddr_str[INET6_ADDRSTRLEN];
struct unpcb64 unp;
char unix_laddr_str[PATH_MAX] = { 0 };
char unix_raddr_str[PATH_MAX] = { 0 };
/* Read file structure */
if (psutil_kread(Kd, fp, (char *)&f, sizeof(f))) {
return NULL;
}
if (!f.f_count || f.f_type != DTYPE_SOCKET) {
return NO_SOCKET;
}
if (psutil_kread(Kd, (KA_T) f.f_data, (char *) &s, sizeof(s))) {
return NULL;
}
if (!s.so_type) {
return NO_SOCKET;
}
if (!s.so_proto) {
PyErr_SetString(PyExc_RuntimeError, "invalid socket protocol handle");
return NULL;
}
if (psutil_kread(Kd, (KA_T)s.so_proto, (char *)&p, sizeof(p))) {
return NULL;
}
if (!p.pr_domain) {
PyErr_SetString(PyExc_RuntimeError, "invalid socket protocol domain");
return NULL;
}
if (psutil_kread(Kd, (KA_T)p.pr_domain, (char *)&d, sizeof(d))) {
return NULL;
}
fam = d.dom_family;
if (fam == AF_INET || fam == AF_INET6) {
/* Read protocol control block */
if (!s.so_pcb) {
PyErr_SetString(PyExc_RuntimeError, "invalid socket PCB");
return NULL;
}
if (psutil_kread(Kd, (KA_T) s.so_pcb, (char *) &inp, sizeof(inp))) {
return NULL;
}
if (p.pr_protocol == IPPROTO_TCP) {
/* If this is a TCP socket, read its control block */
if (inp.inp_ppcb
&& !psutil_kread(Kd, (KA_T)inp.inp_ppcb,
(char *)&t, sizeof(t)))
state = t.t_state;
}
if (fam == AF_INET6) {
laddr = (unsigned char *)&inp.inp_laddr6;
if (!IN6_IS_ADDR_UNSPECIFIED(&inp.inp_faddr6)) {
raddr = (unsigned char *)&inp.inp_faddr6;
rport = (int)ntohs(inp.inp_fport);
}
}
if (fam == AF_INET) {
laddr = (unsigned char *)&inp.inp_laddr;
if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) {
raddr = (unsigned char *)&inp.inp_faddr;
rport = (int)ntohs(inp.inp_fport);
}
}
lport = (int)ntohs(inp.inp_lport);
inet_ntop(fam, laddr, laddr_str, sizeof(laddr_str));
if (raddr != NULL) {
inet_ntop(fam, raddr, raddr_str, sizeof(raddr_str));
return Py_BuildValue("(iii(si)(si)ii)", fd, fam,
s.so_type, laddr_str, lport, raddr_str,
rport, state, pid);
}
else {
return Py_BuildValue("(iii(si)()ii)", fd, fam,
s.so_type, laddr_str, lport, state,
pid);
}
}
if (fam == AF_UNIX) {
if (psutil_kread(Kd, (KA_T) s.so_pcb, (char *)&unp, sizeof(unp))) {
return NULL;
}
if ((KA_T) f.f_data != (KA_T) unp.unp_socket) {
PyErr_SetString(PyExc_RuntimeError, "unp_socket mismatch");
return NULL;
}
if (unp.unp_addr) {
if (read_unp_addr(Kd, unp.unp_addr, unix_laddr_str,
sizeof(unix_laddr_str))) {
return NULL;
}
}
if (unp.unp_conn) {
if (psutil_kread(Kd, (KA_T) unp.unp_conn, (char *)&unp,
sizeof(unp))) {
return NULL;
}
if (read_unp_addr(Kd, unp.unp_addr, unix_raddr_str,
sizeof(unix_raddr_str))) {
return NULL;
}
}
return Py_BuildValue("(iiissii)", fd, d.dom_family,
s.so_type, unix_laddr_str, unix_raddr_str, PSUTIL_CONN_NONE,
pid);
}
return NO_SOCKET;
}
PyObject *
psutil_net_connections(PyObject *self, PyObject *args) {
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
KA_T fp;
int Kd = -1;
int i, np;
struct procentry64 *p;
struct fdsinfo64 *fds = (struct fdsinfo64 *)NULL;
pid32_t requested_pid;
pid32_t pid;
struct procentry64 *processes = (struct procentry64 *)NULL;
/* the process table */
if (py_retlist == NULL)
goto error;
if (! PyArg_ParseTuple(args, "i", &requested_pid))
goto error;
Kd = open(KMEM, O_RDONLY, 0);
if (Kd < 0) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, KMEM);
goto error;
}
processes = psutil_read_process_table(&np);
if (!processes)
goto error;
/* Loop through processes */
for (p = processes; np > 0; np--, p++) {
pid = p->pi_pid;
if (requested_pid != -1 && requested_pid != pid)
continue;
if (p->pi_state == 0 || p->pi_state == SZOMB)
continue;
if (!fds) {
fds = (struct fdsinfo64 *)malloc((size_t)FDSINFOSIZE);
if (!fds) {
PyErr_NoMemory();
goto error;
}
}
if (getprocs64((struct procentry64 *)NULL, PROCSIZE, fds, FDSINFOSIZE,
&pid, 1)
!= 1)
continue;
/* loop over file descriptors */
for (i = 0; i < p->pi_maxofile; i++) {
fp = (KA_T)fds->pi_ufd[i].fp;
if (fp) {
py_tuple = process_file(Kd, p->pi_pid, i, fp);
if (py_tuple == NULL)
goto error;
if (py_tuple != NO_SOCKET) {
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
}
}
}
close(Kd);
free(processes);
if (fds != NULL)
free(fds);
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
if (Kd > 0)
close(Kd);
if (processes != NULL)
free(processes);
if (fds != NULL)
free(fds);
return NULL;
}

15
third_party/python/psutil/psutil/arch/aix/net_connections.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef __NET_CONNECTIONS_H__
#define __NET_CONNECTIONS_H__
#include <Python.h>
PyObject* psutil_net_connections(PyObject *self, PyObject *args);
#endif /* __NET_CONNECTIONS_H__ */

110
third_party/python/psutil/psutil/arch/aix/net_kernel_structs.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,110 @@
/*
* Copyright (c) 2017, Arnon Yaari
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* The kernel is always 64 bit but Python is usually compiled as a 32 bit
* process. We're reading the kernel memory to get the network connections,
* so we need the structs we read to be defined with 64 bit "pointers".
* Here are the partial definitions of the structs we use, taken from the
* header files, with data type sizes converted to their 64 bit counterparts,
* and unused data truncated. */
#ifdef __64BIT__
/* In case we're in a 64 bit process after all */
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/unpcb.h>
#include <sys/mbuf_base.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#define file64 file
#define socket64 socket
#define protosw64 protosw
#define inpcb64 inpcb
#define tcpcb64 tcpcb
#define unpcb64 unpcb
#define mbuf64 mbuf
#else
struct file64 {
int f_flag;
int f_count;
int f_options;
int f_type;
u_longlong_t f_data;
};
struct socket64 {
short so_type; /* generic type, see socket.h */
short so_options; /* from socket call, see socket.h */
ushort so_linger; /* time to linger while closing */
short so_state; /* internal state flags SS_*, below */
u_longlong_t so_pcb; /* protocol control block */
u_longlong_t so_proto; /* protocol handle */
};
struct protosw64 {
short pr_type; /* socket type used for */
u_longlong_t pr_domain; /* domain protocol a member of */
short pr_protocol; /* protocol number */
short pr_flags; /* see below */
};
struct inpcb64 {
u_longlong_t inp_next,inp_prev;
/* pointers to other pcb's */
u_longlong_t inp_head; /* pointer back to chain of inpcb's
for this protocol */
u_int32_t inp_iflowinfo; /* input flow label */
u_short inp_fport; /* foreign port */
u_int16_t inp_fatype; /* foreign address type */
union in_addr_6 inp_faddr_6; /* foreign host table entry */
u_int32_t inp_oflowinfo; /* output flow label */
u_short inp_lport; /* local port */
u_int16_t inp_latype; /* local address type */
union in_addr_6 inp_laddr_6; /* local host table entry */
u_longlong_t inp_socket; /* back pointer to socket */
u_longlong_t inp_ppcb; /* pointer to per-protocol pcb */
u_longlong_t space_rt;
struct sockaddr_in6 spare_dst;
u_longlong_t inp_ifa; /* interface address to use */
int inp_flags; /* generic IP/datagram flags */
};
struct tcpcb64 {
u_longlong_t seg__next;
u_longlong_t seg__prev;
short t_state; /* state of this connection */
};
struct unpcb64 {
u_longlong_t unp_socket; /* pointer back to socket */
u_longlong_t unp_vnode; /* if associated with file */
ino_t unp_vno; /* fake vnode number */
u_longlong_t unp_conn; /* control block of connected socket */
u_longlong_t unp_refs; /* referencing socket linked list */
u_longlong_t unp_nextref; /* link in unp_refs list */
u_longlong_t unp_addr; /* bound address of socket */
};
struct m_hdr64
{
u_longlong_t mh_next; /* next buffer in chain */
u_longlong_t mh_nextpkt; /* next chain in queue/record */
long mh_len; /* amount of data in this mbuf */
u_longlong_t mh_data; /* location of data */
};
struct mbuf64
{
struct m_hdr64 m_hdr;
};
#define m_len m_hdr.mh_len
#endif

Просмотреть файл

@ -1,265 +0,0 @@
/*
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Helper functions related to fetching process information.
* Used by _psutil_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 <signal.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
psutil_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
*psutil_get_cmd_path(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) {
PyErr_NoMemory();
return NULL;
}
*pathsize = size;
if (sysctl(mib, 4, path, &size, NULL, 0) == -1) {
free(path);
return NULL; // Insufficient privileges
}
return path;
}
/*
* XXX no longer used; it probably makese sense to remove it.
* 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
*psutil_get_cmd_args(long pid, size_t *argsize)
{
int mib[4], argmax;
size_t size = sizeof(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) {
PyErr_NoMemory();
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 *
psutil_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;
argstr = psutil_get_cmd_args(pid, &argsize);
if (argstr == NULL)
goto error;
// args are returned as a flattened string with \0 separators between
// arguments add each string to the list then step forward to the next
// separator
if (argsize > 0) {
while (pos < argsize) {
item = Py_BuildValue("s", &argstr[pos]);
if (!item)
goto error;
if (PyList_Append(retlist, item))
goto error;
Py_DECREF(item);
pos = pos + strlen(&argstr[pos]) + 1;
}
}
free(argstr);
return retlist;
error:
Py_XDECREF(item);
Py_DECREF(retlist);
if (argstr != NULL)
free(argstr);
return NULL;
}
/*
* Return 1 if PID exists in the current process list, else 0.
*/
int
psutil_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;
}

Просмотреть файл

@ -1,15 +0,0 @@
/*
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
typedef struct kinfo_proc kinfo_proc;
char *psutil_get_cmd_args(long pid, size_t *argsize);
char *psutil_get_cmd_path(long pid, size_t *pathsize);
int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
int psutil_pid_exists(long pid);
PyObject* psutil_get_arg_list(long pid);

368
third_party/python/psutil/psutil/arch/freebsd/proc_socks.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,368 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Retrieves per-process open socket connections.
*/
#include <Python.h>
#include <sys/user.h>
#include <sys/socketvar.h> // for struct xsocket
#include <sys/un.h>
#include <sys/sysctl.h>
#include <netinet/in.h> // for xinpcb struct
#include <netinet/in_pcb.h>
#include <netinet/tcp_var.h> // for struct xtcpcb
#include <arpa/inet.h> // for inet_ntop()
#include <libutil.h>
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
// The tcplist fetching and walking is borrowed from netstat/inet.c.
static char *
psutil_fetch_tcplist(void) {
char *buf;
size_t len;
for (;;) {
if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
buf = malloc(len);
if (buf == NULL) {
PyErr_NoMemory();
return NULL;
}
if (sysctlbyname("net.inet.tcp.pcblist", buf, &len, NULL, 0) < 0) {
free(buf);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return buf;
}
}
static int
psutil_sockaddr_port(int family, struct sockaddr_storage *ss) {
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
if (family == AF_INET) {
sin = (struct sockaddr_in *)ss;
return (sin->sin_port);
}
else {
sin6 = (struct sockaddr_in6 *)ss;
return (sin6->sin6_port);
}
}
static void *
psutil_sockaddr_addr(int family, struct sockaddr_storage *ss) {
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
if (family == AF_INET) {
sin = (struct sockaddr_in *)ss;
return (&sin->sin_addr);
}
else {
sin6 = (struct sockaddr_in6 *)ss;
return (&sin6->sin6_addr);
}
}
static socklen_t
psutil_sockaddr_addrlen(int family) {
if (family == AF_INET)
return (sizeof(struct in_addr));
else
return (sizeof(struct in6_addr));
}
static int
psutil_sockaddr_matches(int family, int port, void *pcb_addr,
struct sockaddr_storage *ss) {
if (psutil_sockaddr_port(family, ss) != port)
return (0);
return (memcmp(psutil_sockaddr_addr(family, ss), pcb_addr,
psutil_sockaddr_addrlen(family)) == 0);
}
#if __FreeBSD_version >= 1200026
static struct xtcpcb *
psutil_search_tcplist(char *buf, struct kinfo_file *kif) {
struct xtcpcb *tp;
struct xinpcb *inp;
#else
static struct tcpcb *
psutil_search_tcplist(char *buf, struct kinfo_file *kif) {
struct tcpcb *tp;
struct inpcb *inp;
#endif
struct xinpgen *xig, *oxig;
struct xsocket *so;
oxig = xig = (struct xinpgen *)buf;
for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
xig->xig_len > sizeof(struct xinpgen);
xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
#if __FreeBSD_version >= 1200026
tp = (struct xtcpcb *)xig;
inp = &tp->xt_inp;
so = &inp->xi_socket;
#else
tp = &((struct xtcpcb *)xig)->xt_tp;
inp = &((struct xtcpcb *)xig)->xt_inp;
so = &((struct xtcpcb *)xig)->xt_socket;
#endif
if (so->so_type != kif->kf_sock_type ||
so->xso_family != kif->kf_sock_domain ||
so->xso_protocol != kif->kf_sock_protocol)
continue;
if (kif->kf_sock_domain == AF_INET) {
if (!psutil_sockaddr_matches(
AF_INET, inp->inp_lport, &inp->inp_laddr,
#if __FreeBSD_version < 1200031
&kif->kf_sa_local))
#else
&kif->kf_un.kf_sock.kf_sa_local))
#endif
continue;
if (!psutil_sockaddr_matches(
AF_INET, inp->inp_fport, &inp->inp_faddr,
#if __FreeBSD_version < 1200031
&kif->kf_sa_peer))
#else
&kif->kf_un.kf_sock.kf_sa_peer))
#endif
continue;
} else {
if (!psutil_sockaddr_matches(
AF_INET6, inp->inp_lport, &inp->in6p_laddr,
#if __FreeBSD_version < 1200031
&kif->kf_sa_local))
#else
&kif->kf_un.kf_sock.kf_sa_local))
#endif
continue;
if (!psutil_sockaddr_matches(
AF_INET6, inp->inp_fport, &inp->in6p_faddr,
#if __FreeBSD_version < 1200031
&kif->kf_sa_peer))
#else
&kif->kf_un.kf_sock.kf_sa_peer))
#endif
continue;
}
return (tp);
}
return NULL;
}
PyObject *
psutil_proc_connections(PyObject *self, PyObject *args) {
// Return connections opened by process.
long pid;
int i;
int cnt;
struct kinfo_file *freep = NULL;
struct kinfo_file *kif;
char *tcplist = NULL;
#if __FreeBSD_version >= 1200026
struct xtcpcb *tcp;
#else
struct tcpcb *tcp;
#endif
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
PyObject *py_laddr = NULL;
PyObject *py_raddr = NULL;
PyObject *py_af_filter = NULL;
PyObject *py_type_filter = NULL;
PyObject *py_family = NULL;
PyObject *py_type = NULL;
if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "lOO", &pid, &py_af_filter, &py_type_filter))
goto error;
if (!PySequence_Check(py_af_filter) || !PySequence_Check(py_type_filter)) {
PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
goto error;
}
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
tcplist = psutil_fetch_tcplist();
if (tcplist == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
for (i = 0; i < cnt; i++) {
int lport, rport, state;
char lip[200], rip[200];
char path[PATH_MAX];
int inseq;
py_tuple = NULL;
py_laddr = NULL;
py_raddr = NULL;
kif = &freep[i];
if (kif->kf_type == KF_TYPE_SOCKET) {
// apply filters
py_family = PyLong_FromLong((long)kif->kf_sock_domain);
inseq = PySequence_Contains(py_af_filter, py_family);
Py_DECREF(py_family);
if (inseq == 0)
continue;
py_type = PyLong_FromLong((long)kif->kf_sock_type);
inseq = PySequence_Contains(py_type_filter, py_type);
Py_DECREF(py_type);
if (inseq == 0)
continue;
// IPv4 / IPv6 socket
if ((kif->kf_sock_domain == AF_INET) ||
(kif->kf_sock_domain == AF_INET6)) {
// fill status
state = PSUTIL_CONN_NONE;
if (kif->kf_sock_type == SOCK_STREAM) {
tcp = psutil_search_tcplist(tcplist, kif);
if (tcp != NULL)
state = (int)tcp->t_state;
}
// build addr and port
inet_ntop(
kif->kf_sock_domain,
psutil_sockaddr_addr(kif->kf_sock_domain,
#if __FreeBSD_version < 1200031
&kif->kf_sa_local),
#else
&kif->kf_un.kf_sock.kf_sa_local),
#endif
lip,
sizeof(lip));
inet_ntop(
kif->kf_sock_domain,
psutil_sockaddr_addr(kif->kf_sock_domain,
#if __FreeBSD_version < 1200031
&kif->kf_sa_peer),
#else
&kif->kf_un.kf_sock.kf_sa_peer),
#endif
rip,
sizeof(rip));
lport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
#if __FreeBSD_version < 1200031
&kif->kf_sa_local));
#else
&kif->kf_un.kf_sock.kf_sa_local));
#endif
rport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
#if __FreeBSD_version < 1200031
&kif->kf_sa_peer));
#else
&kif->kf_un.kf_sock.kf_sa_peer));
#endif
// construct python tuple/list
py_laddr = Py_BuildValue("(si)", lip, lport);
if (!py_laddr)
goto error;
if (rport != 0)
py_raddr = Py_BuildValue("(si)", rip, rport);
else
py_raddr = Py_BuildValue("()");
if (!py_raddr)
goto error;
py_tuple = Py_BuildValue(
"(iiiNNi)",
kif->kf_fd,
kif->kf_sock_domain,
kif->kf_sock_type,
py_laddr,
py_raddr,
state
);
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
// UNIX socket.
// Note: remote path cannot be determined.
else if (kif->kf_sock_domain == AF_UNIX) {
struct sockaddr_un *sun;
#if __FreeBSD_version < 1200031
sun = (struct sockaddr_un *)&kif->kf_sa_local;
#else
sun = (struct sockaddr_un *)&kif->kf_un.kf_sock.kf_sa_local;
#endif
snprintf(
path, sizeof(path), "%.*s",
(int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
sun->sun_path);
py_laddr = PyUnicode_DecodeFSDefault(path);
if (! py_laddr)
goto error;
py_tuple = Py_BuildValue(
"(iiiOsi)",
kif->kf_fd,
kif->kf_sock_domain,
kif->kf_sock_type,
py_laddr,
"", // raddr can't be determined
PSUTIL_CONN_NONE
);
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
Py_DECREF(py_laddr);
}
}
}
free(freep);
free(tcplist);
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_laddr);
Py_XDECREF(py_raddr);
Py_DECREF(py_retlist);
if (freep != NULL)
free(freep);
if (tcplist != NULL)
free(tcplist);
return NULL;
}

9
third_party/python/psutil/psutil/arch/freebsd/proc_socks.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
PyObject* psutil_proc_connections(PyObject* self, PyObject* args);

1009
third_party/python/psutil/psutil/arch/freebsd/specific.c поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

32
third_party/python/psutil/psutil/arch/freebsd/specific.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
/*
* 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>
typedef struct kinfo_proc kinfo_proc;
int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
int psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc);
//
PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
PyObject* psutil_get_cmdline(long pid);
PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args);
PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args);
PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
PyObject* psutil_cpu_stats(PyObject* self, PyObject* args);
#if defined(PSUTIL_FREEBSD)
PyObject* psutil_sensors_battery(PyObject* self, PyObject* args);
#endif

362
third_party/python/psutil/psutil/arch/freebsd/sys_socks.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,362 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Retrieves system-wide open socket connections. This is based off of
* sockstat utility source code:
* https://github.com/freebsd/freebsd/blob/master/usr.bin/sockstat/sockstat.c
*/
#include <Python.h>
#include <sys/user.h>
#include <sys/file.h>
#include <sys/socketvar.h> // for struct xsocket
#include <sys/un.h>
#include <sys/unpcb.h>
#include <sys/sysctl.h>
#include <netinet/in.h> // for xinpcb struct
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/tcp_var.h> // for struct xtcpcb
#include <arpa/inet.h> // for inet_ntop()
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
static struct xfile *psutil_xfiles;
static int psutil_nxfiles;
int
psutil_populate_xfiles() {
size_t len;
if ((psutil_xfiles = malloc(len = sizeof *psutil_xfiles)) == NULL) {
PyErr_NoMemory();
return 0;
}
while (sysctlbyname("kern.file", psutil_xfiles, &len, 0, 0) == -1) {
if (errno != ENOMEM) {
PyErr_SetFromErrno(0);
return 0;
}
len *= 2;
if ((psutil_xfiles = realloc(psutil_xfiles, len)) == NULL) {
PyErr_NoMemory();
return 0;
}
}
if (len > 0 && psutil_xfiles->xf_size != sizeof *psutil_xfiles) {
PyErr_Format(PyExc_RuntimeError, "struct xfile size mismatch");
return 0;
}
psutil_nxfiles = len / sizeof *psutil_xfiles;
return 1;
}
struct xfile *
psutil_get_file_from_sock(void *sock) {
struct xfile *xf;
int n;
for (xf = psutil_xfiles, n = 0; n < psutil_nxfiles; ++n, ++xf) {
if (xf->xf_data == sock)
return xf;
}
return NULL;
}
// Reference:
// https://github.com/freebsd/freebsd/blob/master/usr.bin/sockstat/sockstat.c
int psutil_gather_inet(int proto, PyObject *py_retlist) {
struct xinpgen *xig, *exig;
struct xinpcb *xip;
struct xtcpcb *xtp;
#if __FreeBSD_version >= 1200026
struct xinpcb *inp;
#else
struct inpcb *inp;
#endif
struct xsocket *so;
const char *varname = NULL;
size_t len, bufsize;
void *buf;
int retry;
int type;
PyObject *py_tuple = NULL;
PyObject *py_laddr = NULL;
PyObject *py_raddr = NULL;
switch (proto) {
case IPPROTO_TCP:
varname = "net.inet.tcp.pcblist";
type = SOCK_STREAM;
break;
case IPPROTO_UDP:
varname = "net.inet.udp.pcblist";
type = SOCK_DGRAM;
break;
}
buf = NULL;
bufsize = 8192;
retry = 5;
do {
for (;;) {
buf = realloc(buf, bufsize);
if (buf == NULL)
continue; // XXX
len = bufsize;
if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
break;
if (errno != ENOMEM) {
PyErr_SetFromErrno(0);
goto error;
}
bufsize *= 2;
}
xig = (struct xinpgen *)buf;
exig = (struct xinpgen *)(void *)((char *)buf + len - sizeof *exig);
if (xig->xig_len != sizeof *xig || exig->xig_len != sizeof *exig) {
PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
goto error;
}
} while (xig->xig_gen != exig->xig_gen && retry--);
for (;;) {
struct xfile *xf;
int lport, rport, status, family;
xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
if (xig >= exig)
break;
switch (proto) {
case IPPROTO_TCP:
xtp = (struct xtcpcb *)xig;
if (xtp->xt_len != sizeof *xtp) {
PyErr_Format(PyExc_RuntimeError,
"struct xtcpcb size mismatch");
goto error;
}
inp = &xtp->xt_inp;
#if __FreeBSD_version >= 1200026
so = &inp->xi_socket;
status = xtp->t_state;
#else
so = &xtp->xt_socket;
status = xtp->xt_tp.t_state;
#endif
break;
case IPPROTO_UDP:
xip = (struct xinpcb *)xig;
if (xip->xi_len != sizeof *xip) {
PyErr_Format(PyExc_RuntimeError,
"struct xinpcb size mismatch");
goto error;
}
#if __FreeBSD_version >= 1200026
inp = xip;
#else
inp = &xip->xi_inp;
#endif
so = &xip->xi_socket;
status = PSUTIL_CONN_NONE;
break;
default:
PyErr_Format(PyExc_RuntimeError, "invalid proto");
goto error;
}
char lip[200], rip[200];
xf = psutil_get_file_from_sock(so->xso_so);
if (xf == NULL)
continue;
lport = ntohs(inp->inp_lport);
rport = ntohs(inp->inp_fport);
if (inp->inp_vflag & INP_IPV4) {
family = AF_INET;
inet_ntop(AF_INET, &inp->inp_laddr.s_addr, lip, sizeof(lip));
inet_ntop(AF_INET, &inp->inp_faddr.s_addr, rip, sizeof(rip));
}
else if (inp->inp_vflag & INP_IPV6) {
family = AF_INET6;
inet_ntop(AF_INET6, &inp->in6p_laddr.s6_addr, lip, sizeof(lip));
inet_ntop(AF_INET6, &inp->in6p_faddr.s6_addr, rip, sizeof(rip));
}
// construct python tuple/list
py_laddr = Py_BuildValue("(si)", lip, lport);
if (!py_laddr)
goto error;
if (rport != 0)
py_raddr = Py_BuildValue("(si)", rip, rport);
else
py_raddr = Py_BuildValue("()");
if (!py_raddr)
goto error;
py_tuple = Py_BuildValue(
"(iiiNNii)",
xf->xf_fd, // fd
family, // family
type, // type
py_laddr, // laddr
py_raddr, // raddr
status, // status
xf->xf_pid); // pid
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
free(buf);
return 1;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_laddr);
Py_XDECREF(py_raddr);
free(buf);
return 0;
}
int psutil_gather_unix(int proto, PyObject *py_retlist) {
struct xunpgen *xug, *exug;
struct xunpcb *xup;
const char *varname = NULL;
const char *protoname = NULL;
size_t len;
size_t bufsize;
void *buf;
int retry;
struct sockaddr_un *sun;
char path[PATH_MAX];
PyObject *py_tuple = NULL;
PyObject *py_lpath = NULL;
switch (proto) {
case SOCK_STREAM:
varname = "net.local.stream.pcblist";
protoname = "stream";
break;
case SOCK_DGRAM:
varname = "net.local.dgram.pcblist";
protoname = "dgram";
break;
}
buf = NULL;
bufsize = 8192;
retry = 5;
do {
for (;;) {
buf = realloc(buf, bufsize);
if (buf == NULL) {
PyErr_NoMemory();
goto error;
}
len = bufsize;
if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
break;
if (errno != ENOMEM) {
PyErr_SetFromErrno(0);
goto error;
}
bufsize *= 2;
}
xug = (struct xunpgen *)buf;
exug = (struct xunpgen *)(void *)
((char *)buf + len - sizeof *exug);
if (xug->xug_len != sizeof *xug || exug->xug_len != sizeof *exug) {
PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch");
goto error;
}
} while (xug->xug_gen != exug->xug_gen && retry--);
for (;;) {
struct xfile *xf;
xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len);
if (xug >= exug)
break;
xup = (struct xunpcb *)xug;
if (xup->xu_len != sizeof *xup)
goto error;
xf = psutil_get_file_from_sock(xup->xu_socket.xso_so);
if (xf == NULL)
continue;
sun = (struct sockaddr_un *)&xup->xu_addr;
snprintf(path, sizeof(path), "%.*s",
(int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
sun->sun_path);
py_lpath = PyUnicode_DecodeFSDefault(path);
if (! py_lpath)
goto error;
py_tuple = Py_BuildValue("(iiiOsii)",
xf->xf_fd, // fd
AF_UNIX, // family
proto, // type
py_lpath, // lpath
"", // rath
PSUTIL_CONN_NONE, // status
xf->xf_pid); // pid
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_lpath);
Py_DECREF(py_tuple);
}
free(buf);
return 1;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_lpath);
free(buf);
return 0;
}
PyObject*
psutil_net_connections(PyObject* self, PyObject* args) {
// Return system-wide open connections.
PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL)
return NULL;
if (psutil_populate_xfiles() != 1)
goto error;
if (psutil_gather_inet(IPPROTO_TCP, py_retlist) == 0)
goto error;
if (psutil_gather_inet(IPPROTO_UDP, py_retlist) == 0)
goto error;
if (psutil_gather_unix(SOCK_STREAM, py_retlist) == 0)
goto error;
if (psutil_gather_unix(SOCK_DGRAM, py_retlist) == 0)
goto error;
free(psutil_xfiles);
return py_retlist;
error:
Py_DECREF(py_retlist);
free(psutil_xfiles);
return NULL;
}

10
third_party/python/psutil/psutil/arch/freebsd/sys_socks.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
PyObject* psutil_net_connections(PyObject* self, PyObject* args);

447
third_party/python/psutil/psutil/arch/netbsd/socks.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,447 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'.
* Copyright (c) 2015, Ryo ONODERA.
* 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/cdefs.h>
#include <arpa/inet.h>
#include <sys/queue.h>
#include <sys/un.h>
#include <sys/file.h>
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
// address family filter
enum af_filter {
INET,
INET4,
INET6,
TCP,
TCP4,
TCP6,
UDP,
UDP4,
UDP6,
UNIX,
ALL,
};
// kinfo_file results
struct kif {
SLIST_ENTRY(kif) kifs;
struct kinfo_file *kif;
};
// kinfo_file results list
SLIST_HEAD(kifhead, kif) kihead = SLIST_HEAD_INITIALIZER(kihead);
// kinfo_pcb results
struct kpcb {
SLIST_ENTRY(kpcb) kpcbs;
struct kinfo_pcb *kpcb;
};
// kinfo_pcb results list
SLIST_HEAD(kpcbhead, kpcb) kpcbhead = SLIST_HEAD_INITIALIZER(kpcbhead);
static void psutil_kiflist_init(void);
static void psutil_kiflist_clear(void);
static void psutil_kpcblist_init(void);
static void psutil_kpcblist_clear(void);
static int psutil_get_files(void);
static int psutil_get_sockets(const char *name);
static int psutil_get_info(int aff);
// Initialize kinfo_file results list.
static void
psutil_kiflist_init(void) {
SLIST_INIT(&kihead);
return;
}
// Clear kinfo_file results list.
static void
psutil_kiflist_clear(void) {
while (!SLIST_EMPTY(&kihead)) {
SLIST_REMOVE_HEAD(&kihead, kifs);
}
return;
}
// Initialize kinof_pcb result list.
static void
psutil_kpcblist_init(void) {
SLIST_INIT(&kpcbhead);
return;
}
// Clear kinof_pcb result list.
static void
psutil_kpcblist_clear(void) {
while (!SLIST_EMPTY(&kpcbhead)) {
SLIST_REMOVE_HEAD(&kpcbhead, kpcbs);
}
return;
}
// Get all open files including socket.
static int
psutil_get_files(void) {
size_t len;
size_t j;
int mib[6];
char *buf;
off_t offset;
mib[0] = CTL_KERN;
mib[1] = KERN_FILE2;
mib[2] = KERN_FILE_BYFILE;
mib[3] = 0;
mib[4] = sizeof(struct kinfo_file);
mib[5] = 0;
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
offset = len % sizeof(off_t);
mib[5] = len / sizeof(struct kinfo_file);
if ((buf = malloc(len + offset)) == NULL) {
PyErr_NoMemory();
return -1;
}
if (sysctl(mib, 6, buf + offset, &len, NULL, 0) == -1) {
free(buf);
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
len /= sizeof(struct kinfo_file);
struct kinfo_file *ki = (struct kinfo_file *)(buf + offset);
for (j = 0; j < len; j++) {
struct kif *kif = malloc(sizeof(struct kif));
kif->kif = &ki[j];
SLIST_INSERT_HEAD(&kihead, kif, kifs);
}
/*
// debug
struct kif *k;
SLIST_FOREACH(k, &kihead, kifs) {
printf("%d\n", k->kif->ki_pid);
}
*/
return 0;
}
// Get open sockets.
static int
psutil_get_sockets(const char *name) {
size_t namelen;
int mib[8];
struct kinfo_pcb *pcb;
size_t len;
size_t j;
memset(mib, 0, sizeof(mib));
if (sysctlnametomib(name, mib, &namelen) == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
if ((pcb = malloc(len)) == NULL) {
PyErr_NoMemory();
return -1;
}
memset(pcb, 0, len);
mib[6] = sizeof(*pcb);
mib[7] = len / sizeof(*pcb);
if (sysctl(mib, __arraycount(mib), pcb, &len, NULL, 0) == -1) {
free(pcb);
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
len /= sizeof(struct kinfo_pcb);
struct kinfo_pcb *kp = (struct kinfo_pcb *)pcb;
for (j = 0; j < len; j++) {
struct kpcb *kpcb = malloc(sizeof(struct kpcb));
kpcb->kpcb = &kp[j];
SLIST_INSERT_HEAD(&kpcbhead, kpcb, kpcbs);
}
/*
// debug
struct kif *k;
struct kpcb *k;
SLIST_FOREACH(k, &kpcbhead, kpcbs) {
printf("ki_type: %d\n", k->kpcb->ki_type);
printf("ki_family: %d\n", k->kpcb->ki_family);
}
*/
return 0;
}
// Collect open file and connections.
static int
psutil_get_info(int aff) {
switch (aff) {
case INET:
if (psutil_get_sockets("net.inet.tcp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet.udp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.tcp6.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.udp6.pcblist") != 0)
return -1;
break;
case INET4:
if (psutil_get_sockets("net.inet.tcp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet.udp.pcblist") != 0)
return -1;
break;
case INET6:
if (psutil_get_sockets("net.inet6.tcp6.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.udp6.pcblist") != 0)
return -1;
break;
case TCP:
if (psutil_get_sockets("net.inet.tcp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.tcp6.pcblist") != 0)
return -1;
break;
case TCP4:
if (psutil_get_sockets("net.inet.tcp.pcblist") != 0)
return -1;
break;
case TCP6:
if (psutil_get_sockets("net.inet6.tcp6.pcblist") != 0)
return -1;
break;
case UDP:
if (psutil_get_sockets("net.inet.udp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.udp6.pcblist") != 0)
return -1;
break;
case UDP4:
if (psutil_get_sockets("net.inet.udp.pcblist") != 0)
return -1;
break;
case UDP6:
if (psutil_get_sockets("net.inet6.udp6.pcblist") != 0)
return -1;
break;
case UNIX:
if (psutil_get_sockets("net.local.stream.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.local.seqpacket.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.local.dgram.pcblist") != 0)
return -1;
break;
case ALL:
if (psutil_get_sockets("net.inet.tcp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet.udp.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.tcp6.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.inet6.udp6.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.local.stream.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.local.seqpacket.pcblist") != 0)
return -1;
if (psutil_get_sockets("net.local.dgram.pcblist") != 0)
return -1;
break;
}
return 0;
}
/*
* Return system-wide connections (unless a pid != -1 is passed).
*/
PyObject *
psutil_net_connections(PyObject *self, PyObject *args) {
char laddr[PATH_MAX];
char raddr[PATH_MAX];
int32_t lport;
int32_t rport;
int32_t status;
pid_t pid;
PyObject *py_tuple = NULL;
PyObject *py_laddr = NULL;
PyObject *py_raddr = NULL;
PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
psutil_kiflist_init();
psutil_kpcblist_init();
if (psutil_get_files() != 0)
goto error;
if (psutil_get_info(ALL) != 0)
goto error;
struct kif *k;
SLIST_FOREACH(k, &kihead, kifs) {
struct kpcb *kp;
if ((pid != -1) && (k->kif->ki_pid != (unsigned int)pid))
continue;
SLIST_FOREACH(kp, &kpcbhead, kpcbs) {
if (k->kif->ki_fdata != kp->kpcb->ki_sockaddr)
continue;
// IPv4 or IPv6
if ((kp->kpcb->ki_family == AF_INET) ||
(kp->kpcb->ki_family == AF_INET6)) {
if (kp->kpcb->ki_family == AF_INET) {
// IPv4
struct sockaddr_in *sin_src =
(struct sockaddr_in *)&kp->kpcb->ki_src;
struct sockaddr_in *sin_dst =
(struct sockaddr_in *)&kp->kpcb->ki_dst;
// source addr and port
inet_ntop(AF_INET, &sin_src->sin_addr, laddr,
sizeof(laddr));
lport = ntohs(sin_src->sin_port);
// remote addr and port
inet_ntop(AF_INET, &sin_dst->sin_addr, raddr,
sizeof(raddr));
rport = ntohs(sin_dst->sin_port);
}
else {
// IPv6
struct sockaddr_in6 *sin6_src =
(struct sockaddr_in6 *)&kp->kpcb->ki_src;
struct sockaddr_in6 *sin6_dst =
(struct sockaddr_in6 *)&kp->kpcb->ki_dst;
// local addr and port
inet_ntop(AF_INET6, &sin6_src->sin6_addr, laddr,
sizeof(laddr));
lport = ntohs(sin6_src->sin6_port);
// remote addr and port
inet_ntop(AF_INET6, &sin6_dst->sin6_addr, raddr,
sizeof(raddr));
rport = ntohs(sin6_dst->sin6_port);
}
// status
if (kp->kpcb->ki_type == SOCK_STREAM)
status = kp->kpcb->ki_tstate;
else
status = PSUTIL_CONN_NONE;
// build addr tuple
py_laddr = Py_BuildValue("(si)", laddr, lport);
if (! py_laddr)
goto error;
if (rport != 0)
py_raddr = Py_BuildValue("(si)", raddr, rport);
else
py_raddr = Py_BuildValue("()");
if (! py_raddr)
goto error;
}
else if (kp->kpcb->ki_family == AF_UNIX) {
// UNIX sockets
struct sockaddr_un *sun_src =
(struct sockaddr_un *)&kp->kpcb->ki_src;
struct sockaddr_un *sun_dst =
(struct sockaddr_un *)&kp->kpcb->ki_dst;
strcpy(laddr, sun_src->sun_path);
strcpy(raddr, sun_dst->sun_path);
status = PSUTIL_CONN_NONE;
py_laddr = PyUnicode_DecodeFSDefault(laddr);
if (! py_laddr)
goto error;
py_raddr = PyUnicode_DecodeFSDefault(raddr);
if (! py_raddr)
goto error;
}
else {
continue;
}
// append tuple to list
py_tuple = Py_BuildValue(
"(iiiOOii)",
k->kif->ki_fd,
kp->kpcb->ki_family,
kp->kpcb->ki_type,
py_laddr,
py_raddr,
status,
k->kif->ki_pid);
if (! py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_laddr);
Py_DECREF(py_raddr);
Py_DECREF(py_tuple);
}
}
psutil_kiflist_clear();
psutil_kpcblist_clear();
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_laddr);
Py_XDECREF(py_raddr);
return 0;
}

10
third_party/python/psutil/psutil/arch/netbsd/socks.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'.
* Copyright (c) 2015, Ryo ONODERA.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
PyObject *psutil_proc_connections(PyObject *, PyObject *);
PyObject *psutil_net_connections(PyObject *, PyObject *);

652
third_party/python/psutil/psutil/arch/netbsd/specific.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,652 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Landry Breuil.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Platform-specific module methods for NetBSD.
*/
#if defined(PSUTIL_NETBSD)
#define _KMEMUSER
#endif
#include <Python.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/swap.h> // for swap_mem
#include <signal.h>
#include <kvm.h>
// connection stuff
#include <netdb.h> // for NI_MAXHOST
#include <sys/socket.h>
#include <sys/sched.h> // for CPUSTATES & CP_*
#define _KERNEL // for DTYPE_*
#include <sys/file.h>
#undef _KERNEL
#include <sys/disk.h> // struct diskstats
#include <netinet/in.h>
#include <arpa/inet.h>
#include "specific.h"
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
#define PSUTIL_KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0)
#define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
// ============================================================================
// Utility functions
// ============================================================================
int
psutil_kinfo_proc(pid_t pid, kinfo_proc *proc) {
// Fills a kinfo_proc struct based on process pid.
int ret;
int mib[6];
size_t size = sizeof(kinfo_proc);
mib[0] = CTL_KERN;
mib[1] = KERN_PROC2;
mib[2] = KERN_PROC_PID;
mib[3] = pid;
mib[4] = size;
mib[5] = 1;
ret = sysctl((int*)mib, 6, proc, &size, NULL, 0);
if (ret == -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;
}
struct kinfo_file *
kinfo_getfile(pid_t pid, int* cnt) {
// Mimic's FreeBSD kinfo_file call, taking a pid and a ptr to an
// int as arg and returns an array with cnt struct kinfo_file.
int mib[6];
size_t len;
struct kinfo_file* kf;
mib[0] = CTL_KERN;
mib[1] = KERN_FILE2;
mib[2] = KERN_FILE_BYPID;
mib[3] = (int) pid;
mib[4] = sizeof(struct kinfo_file);
mib[5] = 0;
// get the size of what would be returned
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
if ((kf = malloc(len)) == NULL) {
PyErr_NoMemory();
return NULL;
}
mib[5] = (int)(len / sizeof(struct kinfo_file));
if (sysctl(mib, 6, kf, &len, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
*cnt = (int)(len / sizeof(struct kinfo_file));
return kf;
}
// XXX: This is no longer used as per
// https://github.com/giampaolo/psutil/pull/557#issuecomment-171912820
// Current implementation uses /proc instead.
// Left here just in case.
/*
PyObject *
psutil_proc_exe(PyObject *self, PyObject *args) {
#if __NetBSD_Version__ >= 799000000
pid_t pid;
char pathname[MAXPATHLEN];
int error;
int mib[4];
int ret;
size_t size;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
if (pid == 0) {
// else returns ENOENT
return Py_BuildValue("s", "");
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROC_ARGS;
mib[2] = pid;
mib[3] = KERN_PROC_PATHNAME;
size = sizeof(pathname);
error = sysctl(mib, 4, NULL, &size, NULL, 0);
if (error == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
error = sysctl(mib, 4, pathname, &size, NULL, 0);
if (error == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
if (size == 0 || strlen(pathname) == 0) {
ret = psutil_pid_exists(pid);
if (ret == -1)
return NULL;
else if (ret == 0)
return NoSuchProcess("");
else
strcpy(pathname, "");
}
return PyUnicode_DecodeFSDefault(pathname);
#else
return Py_BuildValue("s", "");
#endif
}
*/
PyObject *
psutil_proc_num_threads(PyObject *self, PyObject *args) {
// Return number of threads used by process as a Python integer.
long pid;
kinfo_proc kp;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
if (psutil_kinfo_proc(pid, &kp) == -1)
return NULL;
return Py_BuildValue("l", (long)kp.p_nlwps);
}
PyObject *
psutil_proc_threads(PyObject *self, PyObject *args) {
pid_t pid;
int mib[5];
int i, nlwps;
ssize_t st;
size_t size;
struct kinfo_lwp *kl = NULL;
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "l", &pid))
goto error;
mib[0] = CTL_KERN;
mib[1] = KERN_LWP;
mib[2] = pid;
mib[3] = sizeof(struct kinfo_lwp);
mib[4] = 0;
st = sysctl(mib, 5, NULL, &size, NULL, 0);
if (st == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
if (size == 0) {
NoSuchProcess("");
goto error;
}
mib[4] = size / sizeof(size_t);
kl = malloc(size);
if (kl == NULL) {
PyErr_NoMemory();
goto error;
}
st = sysctl(mib, 5, kl, &size, NULL, 0);
if (st == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
if (size == 0) {
NoSuchProcess("");
goto error;
}
nlwps = (int)(size / sizeof(struct kinfo_lwp));
for (i = 0; i < nlwps; i++) {
py_tuple = Py_BuildValue("idd",
(&kl[i])->l_lid,
PSUTIL_KPT2DOUBLE((&kl[i])->l_rtime),
PSUTIL_KPT2DOUBLE((&kl[i])->l_rtime));
if (py_tuple == NULL)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
free(kl);
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
if (kl != NULL)
free(kl);
return NULL;
}
// ============================================================================
// APIS
// ============================================================================
int
psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
// 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.
kinfo_proc *result;
// Declaring name as const requires us to cast it when passing it to
// sysctl because the prototype doesn't include the const modifier.
char errbuf[_POSIX2_LINE_MAX];
int cnt;
kvm_t *kd;
assert( procList != NULL);
assert(*procList == NULL);
assert(procCount != NULL);
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) {
PyErr_Format(
PyExc_RuntimeError, "kvm_openfiles() syscall failed: %s", errbuf);
return errno;
}
result = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(kinfo_proc), &cnt);
if (result == NULL) {
PyErr_Format(PyExc_RuntimeError, "kvm_getproc2() syscall failed");
kvm_close(kd);
return errno;
}
*procCount = (size_t)cnt;
size_t mlen = cnt * sizeof(kinfo_proc);
if ((*procList = malloc(mlen)) == NULL) {
PyErr_NoMemory();
kvm_close(kd);
return errno;
}
memcpy(*procList, result, mlen);
assert(*procList != NULL);
kvm_close(kd);
return 0;
}
char *
psutil_get_cmd_args(pid_t pid, size_t *argsize) {
int mib[4];
ssize_t st;
size_t argmax;
size_t size;
char *procargs = NULL;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(argmax);
st = sysctl(mib, 2, &argmax, &size, NULL, 0);
if (st == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
procargs = (char *)malloc(argmax);
if (procargs == NULL) {
PyErr_NoMemory();
return NULL;
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROC_ARGS;
mib[2] = pid;
mib[3] = KERN_PROC_ARGV;
st = sysctl(mib, 4, procargs, &argmax, NULL, 0);
if (st == -1) {
free(procargs);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
*argsize = argmax;
return procargs;
}
// Return the command line as a python list object.
// XXX - most of the times sysctl() returns a truncated string.
// Also /proc/pid/cmdline behaves the same so it looks like this
// is a kernel bug.
PyObject *
psutil_get_cmdline(pid_t pid) {
char *argstr = NULL;
size_t pos = 0;
size_t argsize = 0;
PyObject *py_arg = NULL;
PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL)
return NULL;
if (pid == 0)
return py_retlist;
argstr = psutil_get_cmd_args(pid, &argsize);
if (argstr == NULL)
goto error;
// args are returned as a flattened string with \0 separators between
// arguments add each string to the list then step forward to the next
// separator
if (argsize > 0) {
while (pos < argsize) {
py_arg = PyUnicode_DecodeFSDefault(&argstr[pos]);
if (!py_arg)
goto error;
if (PyList_Append(py_retlist, py_arg))
goto error;
Py_DECREF(py_arg);
pos = pos + strlen(&argstr[pos]) + 1;
}
}
free(argstr);
return py_retlist;
error:
Py_XDECREF(py_arg);
Py_DECREF(py_retlist);
if (argstr != NULL)
free(argstr);
return NULL;
}
/*
* Virtual memory stats, taken from:
* https://github.com/satterly/zabbix-stats/blob/master/src/libs/zbxsysinfo/
* netbsd/memory.c
*/
PyObject *
psutil_virtual_mem(PyObject *self, PyObject *args) {
size_t size;
struct uvmexp_sysctl uv;
int mib[] = {CTL_VM, VM_UVMEXP2};
long pagesize = getpagesize();
size = sizeof(uv);
if (sysctl(mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return Py_BuildValue("KKKKKKKK",
(unsigned long long) uv.npages << uv.pageshift, // total
(unsigned long long) uv.free << uv.pageshift, // free
(unsigned long long) uv.active << uv.pageshift, // active
(unsigned long long) uv.inactive << uv.pageshift, // inactive
(unsigned long long) uv.wired << uv.pageshift, // wired
(unsigned long long) uv.filepages + uv.execpages * pagesize, // cached
// These are determined from /proc/meminfo in Python.
(unsigned long long) 0, // buffers
(unsigned long long) 0 // shared
);
}
PyObject *
psutil_swap_mem(PyObject *self, PyObject *args) {
uint64_t swap_total, swap_free;
struct swapent *swdev;
int nswap, i;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0) {
// This means there's no swap partition.
return Py_BuildValue("(iiiii)", 0, 0, 0, 0, 0);
}
swdev = calloc(nswap, sizeof(*swdev));
if (swdev == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
if (swapctl(SWAP_STATS, swdev, nswap) == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
// Total things up.
swap_total = swap_free = 0;
for (i = 0; i < nswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
swap_total += swdev[i].se_nblks * DEV_BSIZE;
swap_free += (swdev[i].se_nblks - swdev[i].se_inuse) * DEV_BSIZE;
}
}
free(swdev);
// Get swap in/out
unsigned int total;
size_t size = sizeof(total);
struct uvmexp_sysctl uv;
int mib[] = {CTL_VM, VM_UVMEXP2};
long pagesize = getpagesize();
size = sizeof(uv);
if (sysctl(mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
return Py_BuildValue("(LLLll)",
swap_total,
(swap_total - swap_free),
swap_free,
(long) uv.pgswapin * pagesize, // swap in
(long) uv.pgswapout * pagesize); // swap out
error:
free(swdev);
return NULL;
}
PyObject *
psutil_proc_num_fds(PyObject *self, PyObject *args) {
long pid;
int cnt;
struct kinfo_file *freep;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
psutil_raise_for_pid(pid, "kinfo_getfile()");
return NULL;
}
free(freep);
return Py_BuildValue("i", cnt);
}
PyObject *
psutil_per_cpu_times(PyObject *self, PyObject *args) {
// XXX: why static?
int mib[3];
int ncpu;
size_t len;
size_t size;
int i;
PyObject *py_cputime = NULL;
PyObject *py_retlist = PyList_New(0);
if (py_retlist == NULL)
return NULL;
// 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(PyExc_OSError);
goto error;
}
uint64_t cpu_time[CPUSTATES];
for (i = 0; i < ncpu; i++) {
// per-cpu info
mib[0] = CTL_KERN;
mib[1] = KERN_CP_TIME;
mib[2] = i;
size = sizeof(cpu_time);
if (sysctl(mib, 3, &cpu_time, &size, NULL, 0) == -1) {
warn("failed to get kern.cptime2");
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
py_cputime = 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);
if (!py_cputime)
goto error;
if (PyList_Append(py_retlist, py_cputime))
goto error;
Py_DECREF(py_cputime);
}
return py_retlist;
error:
Py_XDECREF(py_cputime);
Py_DECREF(py_retlist);
return NULL;
}
PyObject *
psutil_disk_io_counters(PyObject *self, PyObject *args) {
int i, dk_ndrive, mib[3];
size_t len;
struct io_sysctl *stats = NULL;
PyObject *py_disk_info = NULL;
PyObject *py_retdict = PyDict_New();
if (py_retdict == NULL)
return NULL;
mib[0] = CTL_HW;
mib[1] = HW_IOSTATS;
mib[2] = sizeof(struct io_sysctl);
len = 0;
if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) {
warn("can't get HW_IOSTATS");
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
dk_ndrive = (int)(len / sizeof(struct io_sysctl));
stats = malloc(len);
if (stats == NULL) {
PyErr_NoMemory();
goto error;
}
if (sysctl(mib, 3, stats, &len, NULL, 0) < 0 ) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
for (i = 0; i < dk_ndrive; i++) {
py_disk_info = Py_BuildValue(
"(KKKK)",
stats[i].rxfer,
stats[i].wxfer,
stats[i].rbytes,
stats[i].wbytes
);
if (!py_disk_info)
goto error;
if (PyDict_SetItemString(py_retdict, stats[i].name, py_disk_info))
goto error;
Py_DECREF(py_disk_info);
}
free(stats);
return py_retdict;
error:
Py_XDECREF(py_disk_info);
Py_DECREF(py_retdict);
if (stats != NULL)
free(stats);
return NULL;
}
PyObject *
psutil_cpu_stats(PyObject *self, PyObject *args) {
size_t size;
struct uvmexp_sysctl uv;
int uvmexp_mib[] = {CTL_VM, VM_UVMEXP2};
size = sizeof(uv);
if (sysctl(uvmexp_mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return Py_BuildValue(
"IIIIIII",
uv.swtch, // ctx switches
uv.intrs, // interrupts - XXX always 0, will be determined via /proc
uv.softs, // soft interrupts
uv.syscalls, // syscalls - XXX always 0
uv.traps, // traps
uv.faults, // faults
uv.forks // forks
);
}

28
third_party/python/psutil/psutil/arch/netbsd/specific.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,28 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Landry Breuil.
* 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>
typedef struct kinfo_proc2 kinfo_proc;
int psutil_kinfo_proc(pid_t pid, kinfo_proc *proc);
struct kinfo_file * kinfo_getfile(pid_t pid, int* cnt);
int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
char *psutil_get_cmd_args(pid_t pid, size_t *argsize);
//
PyObject *psutil_get_cmdline(pid_t pid);
PyObject *psutil_proc_threads(PyObject *self, PyObject *args);
PyObject *psutil_virtual_mem(PyObject *self, PyObject *args);
PyObject *psutil_swap_mem(PyObject *self, PyObject *args);
PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args);
PyObject *psutil_proc_connections(PyObject *self, PyObject *args);
PyObject *psutil_per_cpu_times(PyObject *self, PyObject *args);
PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
PyObject* psutil_cpu_stats(PyObject* self, PyObject* args);

791
third_party/python/psutil/psutil/arch/openbsd/specific.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,791 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Landry Breuil.
* All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Platform-specific module methods for OpenBSD.
*/
#include <Python.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/mount.h> // for VFS_*
#include <sys/swap.h> // for swap_mem
#include <sys/vmmeter.h> // for vmtotal struct
#include <signal.h>
#include <kvm.h>
// connection stuff
#include <netdb.h> // for NI_MAXHOST
#include <sys/socket.h>
#include <sys/sched.h> // for CPUSTATES & CP_*
#define _KERNEL // for DTYPE_*
#include <sys/file.h>
#undef _KERNEL
#include <sys/disk.h> // struct diskstats
#include <arpa/inet.h> // for inet_ntoa()
#include <err.h> // for warn() & err()
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
#define PSUTIL_KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0)
// #define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
// ============================================================================
// Utility functions
// ============================================================================
int
psutil_kinfo_proc(pid_t pid, struct kinfo_proc *proc) {
// Fills a kinfo_proc struct based on process pid.
int ret;
int mib[6];
size_t size = sizeof(struct kinfo_proc);
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = pid;
mib[4] = size;
mib[5] = 1;
ret = sysctl((int*)mib, 6, proc, &size, NULL, 0);
if (ret == -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;
}
struct kinfo_file *
kinfo_getfile(long pid, int* cnt) {
// Mimic's FreeBSD kinfo_file call, taking a pid and a ptr to an
// int as arg and returns an array with cnt struct kinfo_file.
int mib[6];
size_t len;
struct kinfo_file* kf;
mib[0] = CTL_KERN;
mib[1] = KERN_FILE;
mib[2] = KERN_FILE_BYPID;
mib[3] = (int) pid;
mib[4] = sizeof(struct kinfo_file);
mib[5] = 0;
/* get the size of what would be returned */
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
if ((kf = malloc(len)) == NULL) {
PyErr_NoMemory();
return NULL;
}
mib[5] = (int)(len / sizeof(struct kinfo_file));
if (sysctl(mib, 6, kf, &len, NULL, 0) < 0) {
free(kf);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
*cnt = (int)(len / sizeof(struct kinfo_file));
return kf;
}
// ============================================================================
// APIS
// ============================================================================
int
psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) {
// 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.
struct kinfo_proc *result;
// Declaring name as const requires us to cast it when passing it to
// sysctl because the prototype doesn't include the const modifier.
char errbuf[_POSIX2_LINE_MAX];
int cnt;
kvm_t *kd;
assert(procList != NULL);
assert(*procList == NULL);
assert(procCount != NULL);
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) {
return errno;
}
result = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cnt);
if (result == NULL) {
kvm_close(kd);
err(1, NULL);
return errno;
}
*procCount = (size_t)cnt;
size_t mlen = cnt * sizeof(struct kinfo_proc);
if ((*procList = malloc(mlen)) == NULL) {
kvm_close(kd);
err(1, NULL);
return errno;
}
memcpy(*procList, result, mlen);
assert(*procList != NULL);
kvm_close(kd);
return 0;
}
char **
_psutil_get_argv(long pid) {
static char **argv;
int argv_mib[] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};
size_t argv_size = 128;
// Loop and reallocate until we have enough space to fit argv.
for (;; argv_size *= 2) {
if (argv_size >= 8192) {
PyErr_SetString(PyExc_RuntimeError,
"can't allocate enough space for KERN_PROC_ARGV");
return NULL;
}
if ((argv = realloc(argv, argv_size)) == NULL)
continue;
if (sysctl(argv_mib, 4, argv, &argv_size, NULL, 0) == 0)
return argv;
if (errno == ENOMEM)
continue;
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
}
// returns the command line as a python list object
PyObject *
psutil_get_cmdline(long pid) {
static char **argv;
char **p;
PyObject *py_arg = NULL;
PyObject *py_retlist = Py_BuildValue("[]");
if (!py_retlist)
return NULL;
if (pid < 0)
return py_retlist;
if ((argv = _psutil_get_argv(pid)) == NULL)
goto error;
for (p = argv; *p != NULL; p++) {
py_arg = PyUnicode_DecodeFSDefault(*p);
if (!py_arg)
goto error;
if (PyList_Append(py_retlist, py_arg))
goto error;
Py_DECREF(py_arg);
}
return py_retlist;
error:
Py_XDECREF(py_arg);
Py_DECREF(py_retlist);
return NULL;
}
PyObject *
psutil_proc_threads(PyObject *self, PyObject *args) {
// OpenBSD reference:
// https://github.com/janmojzis/pstree/blob/master/proc_kvm.c
// Note: this requires root access, else it will fail trying
// to access /dev/kmem.
long pid;
kvm_t *kd = NULL;
int nentries, i;
char errbuf[4096];
struct kinfo_proc *kp;
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "l", &pid))
goto error;
kd = kvm_openfiles(0, 0, 0, O_RDONLY, errbuf);
if (! kd) {
if (strstr(errbuf, "Permission denied") != NULL)
AccessDenied("");
else
PyErr_Format(PyExc_RuntimeError, "kvm_openfiles() syscall failed");
goto error;
}
kp = kvm_getprocs(
kd, KERN_PROC_PID | KERN_PROC_SHOW_THREADS | KERN_PROC_KTHREAD, pid,
sizeof(*kp), &nentries);
if (! kp) {
if (strstr(errbuf, "Permission denied") != NULL)
AccessDenied("");
else
PyErr_Format(PyExc_RuntimeError, "kvm_getprocs() syscall failed");
goto error;
}
for (i = 0; i < nentries; i++) {
if (kp[i].p_tid < 0)
continue;
if (kp[i].p_pid == pid) {
py_tuple = Py_BuildValue(
"Idd",
kp[i].p_tid,
PSUTIL_KPT2DOUBLE(kp[i].p_uutime),
PSUTIL_KPT2DOUBLE(kp[i].p_ustime));
if (py_tuple == NULL)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
}
kvm_close(kd);
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
if (kd != NULL)
kvm_close(kd);
return NULL;
}
PyObject *
psutil_virtual_mem(PyObject *self, PyObject *args) {
int64_t total_physmem;
int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
int physmem_mib[] = {CTL_HW, HW_PHYSMEM64};
int vmmeter_mib[] = {CTL_VM, VM_METER};
size_t size;
struct uvmexp uvmexp;
struct bcachestats bcstats;
struct vmtotal vmdata;
long pagesize = getpagesize();
size = sizeof(total_physmem);
if (sysctl(physmem_mib, 2, &total_physmem, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
size = sizeof(uvmexp);
if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
size = sizeof(bcstats);
if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
size = sizeof(vmdata);
if (sysctl(vmmeter_mib, 2, &vmdata, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return Py_BuildValue("KKKKKKKK",
// Note: many programs calculate total memory as
// "uvmexp.npages * pagesize" but this is incorrect and does not
// match "sysctl | grep hw.physmem".
(unsigned long long) total_physmem,
(unsigned long long) uvmexp.free * pagesize,
(unsigned long long) uvmexp.active * pagesize,
(unsigned long long) uvmexp.inactive * pagesize,
(unsigned long long) uvmexp.wired * pagesize,
// this is how "top" determines it
(unsigned long long) bcstats.numbufpages * pagesize, // cached
(unsigned long long) 0, // buffers
(unsigned long long) vmdata.t_vmshr + vmdata.t_rmshr // shared
);
}
PyObject *
psutil_swap_mem(PyObject *self, PyObject *args) {
uint64_t swap_total, swap_free;
struct swapent *swdev;
int nswap, i;
if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) == 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
if ((swdev = calloc(nswap, sizeof(*swdev))) == NULL) {
PyErr_NoMemory();
return NULL;
}
if (swapctl(SWAP_STATS, swdev, nswap) == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
// Total things up.
swap_total = swap_free = 0;
for (i = 0; i < nswap; i++) {
if (swdev[i].se_flags & SWF_ENABLE) {
swap_free += (swdev[i].se_nblks - swdev[i].se_inuse);
swap_total += swdev[i].se_nblks;
}
}
free(swdev);
return Py_BuildValue("(LLLII)",
swap_total * DEV_BSIZE,
(swap_total - swap_free) * DEV_BSIZE,
swap_free * DEV_BSIZE,
// swap in / swap out is not supported as the
// swapent struct does not provide any info
// about it.
0, 0);
error:
free(swdev);
return NULL;
}
PyObject *
psutil_proc_num_fds(PyObject *self, PyObject *args) {
long pid;
int cnt;
struct kinfo_file *freep;
struct kinfo_proc kipp;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
if (psutil_kinfo_proc(pid, &kipp) == -1)
return NULL;
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
psutil_raise_for_pid(pid, "kinfo_getfile()");
return NULL;
}
free(freep);
return Py_BuildValue("i", cnt);
}
PyObject *
psutil_proc_cwd(PyObject *self, PyObject *args) {
// Reference:
// https://github.com/openbsd/src/blob/
// 588f7f8c69786211f2d16865c552afb91b1c7cba/bin/ps/print.c#L191
long pid;
struct kinfo_proc kp;
char path[MAXPATHLEN];
size_t pathlen = sizeof path;
if (! PyArg_ParseTuple(args, "l", &pid))
return NULL;
if (psutil_kinfo_proc(pid, &kp) == -1)
return NULL;
int name[] = { CTL_KERN, KERN_PROC_CWD, pid };
if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyUnicode_DecodeFSDefault(path);
}
// see sys/kern/kern_sysctl.c lines 1100 and
// usr.bin/fstat/fstat.c print_inet_details()
static char *
psutil_convert_ipv4(int family, uint32_t addr[4]) {
struct in_addr a;
memcpy(&a, addr, sizeof(a));
return inet_ntoa(a);
}
static char *
psutil_inet6_addrstr(struct in6_addr *p)
{
struct sockaddr_in6 sin6;
static char hbuf[NI_MAXHOST];
const int niflags = NI_NUMERICHOST;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_addr = *p;
if (IN6_IS_ADDR_LINKLOCAL(p) &&
*(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) {
sin6.sin6_scope_id =
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = sin6.sin6_addr.s6_addr[3] = 0;
}
if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
hbuf, sizeof(hbuf), NULL, 0, niflags))
return "invalid";
return hbuf;
}
/*
* List process connections.
* Note: there is no net_connections() on OpenBSD. The Python
* implementation will iterate over all processes and use this
* function.
* Note: local and remote paths cannot be determined for UNIX sockets.
*/
PyObject *
psutil_proc_connections(PyObject *self, PyObject *args) {
long pid;
int i;
int cnt;
struct kinfo_file *freep = NULL;
struct kinfo_file *kif;
char *tcplist = NULL;
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
PyObject *py_laddr = NULL;
PyObject *py_raddr = NULL;
PyObject *py_af_filter = NULL;
PyObject *py_type_filter = NULL;
PyObject *py_family = NULL;
PyObject *_type = NULL;
if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "lOO", &pid, &py_af_filter, &py_type_filter))
goto error;
if (!PySequence_Check(py_af_filter) || !PySequence_Check(py_type_filter)) {
PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
goto error;
}
errno = 0;
freep = kinfo_getfile(pid, &cnt);
if (freep == NULL) {
psutil_raise_for_pid(pid, "kinfo_getfile()");
goto error;
}
for (i = 0; i < cnt; i++) {
int state;
int lport;
int rport;
char addrbuf[NI_MAXHOST + 2];
int inseq;
struct in6_addr laddr6;
py_tuple = NULL;
py_laddr = NULL;
py_raddr = NULL;
kif = &freep[i];
if (kif->f_type == DTYPE_SOCKET) {
// apply filters
py_family = PyLong_FromLong((long)kif->so_family);
inseq = PySequence_Contains(py_af_filter, py_family);
Py_DECREF(py_family);
if (inseq == 0)
continue;
_type = PyLong_FromLong((long)kif->so_type);
inseq = PySequence_Contains(py_type_filter, _type);
Py_DECREF(_type);
if (inseq == 0)
continue;
// IPv4 / IPv6 socket
if ((kif->so_family == AF_INET) || (kif->so_family == AF_INET6)) {
// fill status
if (kif->so_type == SOCK_STREAM)
state = kif->t_state;
else
state = PSUTIL_CONN_NONE;
// ports
lport = ntohs(kif->inp_lport);
rport = ntohs(kif->inp_fport);
// local address, IPv4
if (kif->so_family == AF_INET) {
py_laddr = Py_BuildValue(
"(si)",
psutil_convert_ipv4(kif->so_family, kif->inp_laddru),
lport);
if (!py_laddr)
goto error;
}
else {
// local address, IPv6
memcpy(&laddr6, kif->inp_laddru, sizeof(laddr6));
snprintf(addrbuf, sizeof(addrbuf), "%s",
psutil_inet6_addrstr(&laddr6));
py_laddr = Py_BuildValue("(si)", addrbuf, lport);
if (!py_laddr)
goto error;
}
if (rport != 0) {
// remote address, IPv4
if (kif->so_family == AF_INET) {
py_raddr = Py_BuildValue(
"(si)",
psutil_convert_ipv4(
kif->so_family, kif->inp_faddru),
rport);
}
else {
// remote address, IPv6
memcpy(&laddr6, kif->inp_faddru, sizeof(laddr6));
snprintf(addrbuf, sizeof(addrbuf), "%s",
psutil_inet6_addrstr(&laddr6));
py_raddr = Py_BuildValue("(si)", addrbuf, rport);
if (!py_raddr)
goto error;
}
}
else {
py_raddr = Py_BuildValue("()");
}
if (!py_raddr)
goto error;
py_tuple = Py_BuildValue(
"(iiiNNi)",
kif->fd_fd,
kif->so_family,
kif->so_type,
py_laddr,
py_raddr,
state);
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
}
// UNIX socket.
// XXX: local addr is supposed to be in "unp_path" but it
// always empty; also "fstat" command is not able to show
// UNIX socket paths.
else if (kif->so_family == AF_UNIX) {
py_tuple = Py_BuildValue(
"(iiissi)",
kif->fd_fd,
kif->so_family,
kif->so_type,
"", // laddr (kif->unp_path is empty)
"", // raddr
PSUTIL_CONN_NONE);
if (!py_tuple)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_tuple);
Py_INCREF(Py_None);
}
}
}
free(freep);
free(tcplist);
return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_laddr);
Py_XDECREF(py_raddr);
Py_DECREF(py_retlist);
if (freep != NULL)
free(freep);
if (tcplist != NULL)
free(tcplist);
return NULL;
}
PyObject *
psutil_per_cpu_times(PyObject *self, PyObject *args) {
int mib[3];
int ncpu;
size_t len;
size_t size;
int i;
PyObject *py_retlist = PyList_New(0);
PyObject *py_cputime = NULL;
if (py_retlist == NULL)
return NULL;
// 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(PyExc_OSError);
goto error;
}
uint64_t cpu_time[CPUSTATES];
for (i = 0; i < ncpu; i++) {
// per-cpu info
mib[0] = CTL_KERN;
mib[1] = KERN_CPTIME2;
mib[2] = i;
size = sizeof(cpu_time);
if (sysctl(mib, 3, &cpu_time, &size, NULL, 0) == -1) {
warn("failed to get kern.cptime2");
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
py_cputime = 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);
if (!py_cputime)
goto error;
if (PyList_Append(py_retlist, py_cputime))
goto error;
Py_DECREF(py_cputime);
}
return py_retlist;
error:
Py_XDECREF(py_cputime);
Py_DECREF(py_retlist);
return NULL;
}
PyObject *
psutil_disk_io_counters(PyObject *self, PyObject *args) {
int i, dk_ndrive, mib[3];
size_t len;
struct diskstats *stats = NULL;
PyObject *py_retdict = PyDict_New();
PyObject *py_disk_info = NULL;
if (py_retdict == NULL)
return NULL;
mib[0] = CTL_HW;
mib[1] = HW_DISKSTATS;
len = 0;
if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0) {
warn("can't get hw.diskstats size");
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
dk_ndrive = (int)(len / sizeof(struct diskstats));
stats = malloc(len);
if (stats == NULL) {
warn("can't malloc");
PyErr_NoMemory();
goto error;
}
if (sysctl(mib, 2, stats, &len, NULL, 0) < 0 ) {
warn("could not read hw.diskstats");
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
for (i = 0; i < dk_ndrive; i++) {
py_disk_info = Py_BuildValue(
"(KKKK)",
stats[i].ds_rxfer, // num reads
stats[i].ds_wxfer, // num writes
stats[i].ds_rbytes, // read bytes
stats[i].ds_wbytes // write bytes
);
if (!py_disk_info)
goto error;
if (PyDict_SetItemString(py_retdict, stats[i].ds_name, py_disk_info))
goto error;
Py_DECREF(py_disk_info);
}
free(stats);
return py_retdict;
error:
Py_XDECREF(py_disk_info);
Py_DECREF(py_retdict);
if (stats != NULL)
free(stats);
return NULL;
}
PyObject *
psutil_cpu_stats(PyObject *self, PyObject *args) {
size_t size;
struct uvmexp uv;
int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
size = sizeof(uv);
if (sysctl(uvmexp_mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return Py_BuildValue(
"IIIIIII",
uv.swtch, // ctx switches
uv.intrs, // interrupts - XXX always 0, will be determined via /proc
uv.softs, // soft interrupts
uv.syscalls, // syscalls - XXX always 0
uv.traps, // traps
uv.faults, // faults
uv.forks // forks
);
}

27
third_party/python/psutil/psutil/arch/openbsd/specific.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,27 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Landry Breuil.
* 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>
typedef struct kinfo_proc kinfo_proc;
int psutil_kinfo_proc(pid_t pid, struct kinfo_proc *proc);
struct kinfo_file * kinfo_getfile(long pid, int* cnt);
int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
char **_psutil_get_argv(long pid);
PyObject * psutil_get_cmdline(long pid);
//
PyObject *psutil_proc_threads(PyObject *self, PyObject *args);
PyObject *psutil_virtual_mem(PyObject *self, PyObject *args);
PyObject *psutil_swap_mem(PyObject *self, PyObject *args);
PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args);
PyObject *psutil_proc_cwd(PyObject *self, PyObject *args);
PyObject *psutil_proc_connections(PyObject *self, PyObject *args);
PyObject *psutil_per_cpu_times(PyObject *self, PyObject *args);
PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
PyObject* psutil_cpu_stats(PyObject* self, PyObject* args);

Просмотреть файл

@ -21,28 +21,7 @@
#include "process_info.h" #include "process_info.h"
#include "../../_psutil_common.h" #include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
/*
* Return 1 if PID exists in the current process list, else 0.
*/
int
psutil_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 * Returns a list of all BSD processes on the system. This routine
@ -53,14 +32,12 @@ psutil_pid_exists(long pid)
* On error, the function returns a BSD errno value. * On error, the function returns a BSD errno value.
*/ */
int int
psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
{ int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
// Declaring mib as const requires use of a cast since the size_t size, size2;
// sysctl prototype doesn't include the const modifier. void *ptr;
static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; int err;
size_t size, size2; int lim = 8; // some limit
void *ptr;
int err, lim = 8; // some limit
assert( procList != NULL); assert( procList != NULL);
assert(*procList == NULL); assert(*procList == NULL);
@ -116,8 +93,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount)
// Read the maximum argument size for processes // Read the maximum argument size for processes
int int
psutil_get_argmax() psutil_get_argmax() {
{
int argmax; int argmax;
int mib[] = { CTL_KERN, KERN_ARGMAX }; int mib[] = { CTL_KERN, KERN_ARGMAX };
size_t size = sizeof(argmax); size_t size = sizeof(argmax);
@ -130,18 +106,18 @@ psutil_get_argmax()
// return process args as a python list // return process args as a python list
PyObject * PyObject *
psutil_get_arg_list(long pid) psutil_get_cmdline(long pid) {
{
int mib[3]; int mib[3];
int nargs; int nargs;
int len; size_t len;
char *procargs = NULL; char *procargs = NULL;
char *arg_ptr; char *arg_ptr;
char *arg_end; char *arg_end;
char *curr_arg; char *curr_arg;
size_t argmax; size_t argmax;
PyObject *arg = NULL;
PyObject *arglist = NULL; PyObject *py_arg = NULL;
PyObject *py_retlist = NULL;
// special case for PID 0 (kernel_task) where cmdline cannot be fetched // special case for PID 0 (kernel_task) where cmdline cannot be fetched
if (pid == 0) if (pid == 0)
@ -163,15 +139,14 @@ psutil_get_arg_list(long pid)
// read argument space // read argument space
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2; mib[1] = KERN_PROCARGS2;
mib[2] = pid; mib[2] = (pid_t)pid;
if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) { if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
if (EINVAL == errno) { // In case of zombie process we'll get EINVAL. We translate it
// EINVAL == access denied OR nonexistent PID // to NSP and _psosx.py will translate it to ZP.
if (psutil_pid_exists(pid)) if ((errno == EINVAL) && (psutil_pid_exists(pid)))
AccessDenied(); NoSuchProcess("");
else else
NoSuchProcess(); PyErr_SetFromErrno(PyExc_OSError);
}
goto error; goto error;
} }
@ -196,17 +171,17 @@ psutil_get_arg_list(long pid)
// iterate through arguments // iterate through arguments
curr_arg = arg_ptr; curr_arg = arg_ptr;
arglist = Py_BuildValue("[]"); py_retlist = Py_BuildValue("[]");
if (!arglist) if (!py_retlist)
goto error; goto error;
while (arg_ptr < arg_end && nargs > 0) { while (arg_ptr < arg_end && nargs > 0) {
if (*arg_ptr++ == '\0') { if (*arg_ptr++ == '\0') {
arg = Py_BuildValue("s", curr_arg); py_arg = PyUnicode_DecodeFSDefault(curr_arg);
if (!arg) if (! py_arg)
goto error; goto error;
if (PyList_Append(arglist, arg)) if (PyList_Append(py_retlist, py_arg))
goto error; goto error;
Py_DECREF(arg); Py_DECREF(py_arg);
// iterate to next arg and decrement # of args // iterate to next arg and decrement # of args
curr_arg = arg_ptr; curr_arg = arg_ptr;
nargs--; nargs--;
@ -214,26 +189,142 @@ psutil_get_arg_list(long pid)
} }
free(procargs); free(procargs);
return arglist; return py_retlist;
error: error:
Py_XDECREF(arg); Py_XDECREF(py_arg);
Py_XDECREF(arglist); Py_XDECREF(py_retlist);
if (procargs != NULL) if (procargs != NULL)
free(procargs); free(procargs);
return NULL; return NULL;
} }
// return process environment as a python string
PyObject *
psutil_get_environ(long pid) {
int mib[3];
int nargs;
char *procargs = NULL;
char *procenv = NULL;
char *arg_ptr;
char *arg_end;
char *env_start;
size_t argmax;
PyObject *py_ret = NULL;
// special case for PID 0 (kernel_task) where cmdline cannot be fetched
if (pid == 0)
goto empty;
// read argmax and allocate memory for argument space.
argmax = psutil_get_argmax();
if (! argmax) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
procargs = (char *)malloc(argmax);
if (NULL == procargs) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
// read argument space
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = (pid_t)pid;
if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
// In case of zombie process we'll get EINVAL. We translate it
// to NSP and _psosx.py will translate it to ZP.
if ((errno == EINVAL) && (psutil_pid_exists(pid)))
NoSuchProcess("");
else
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
arg_end = &procargs[argmax];
// copy the number of arguments to nargs
memcpy(&nargs, procargs, sizeof(nargs));
// skip executable path
arg_ptr = procargs + sizeof(nargs);
arg_ptr = memchr(arg_ptr, '\0', arg_end - arg_ptr);
if (arg_ptr == NULL || arg_ptr == arg_end)
goto empty;
// skip ahead to the first argument
for (; arg_ptr < arg_end; arg_ptr++) {
if (*arg_ptr != '\0')
break;
}
// iterate through arguments
while (arg_ptr < arg_end && nargs > 0) {
if (*arg_ptr++ == '\0')
nargs--;
}
// build an environment variable block
env_start = arg_ptr;
procenv = calloc(1, arg_end - arg_ptr);
if (procenv == NULL) {
PyErr_NoMemory();
goto error;
}
while (*arg_ptr != '\0' && arg_ptr < arg_end) {
char *s = memchr(arg_ptr + 1, '\0', arg_end - arg_ptr);
if (s == NULL)
break;
memcpy(procenv + (arg_ptr - env_start), arg_ptr, s - arg_ptr);
arg_ptr = s + 1;
}
py_ret = PyUnicode_DecodeFSDefaultAndSize(
procenv, arg_ptr - env_start + 1);
if (!py_ret) {
// XXX: don't want to free() this as per:
// https://github.com/giampaolo/psutil/issues/926
// It sucks but not sure what else to do.
procargs = NULL;
goto error;
}
free(procargs);
free(procenv);
return py_ret;
empty:
if (procargs != NULL)
free(procargs);
return Py_BuildValue("s", "");
error:
Py_XDECREF(py_ret);
if (procargs != NULL)
free(procargs);
if (procenv != NULL)
free(procargs);
return NULL;
}
int int
psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp) psutil_get_kinfo_proc(long pid, struct kinfo_proc *kp) {
{
int mib[4]; int mib[4];
size_t len; size_t len;
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_PROC; mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID; mib[2] = KERN_PROC_PID;
mib[3] = pid; mib[3] = (pid_t)pid;
// fetch the info with sysctl() // fetch the info with sysctl()
len = sizeof(struct kinfo_proc); len = sizeof(struct kinfo_proc);
@ -247,7 +338,7 @@ psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
// sysctl succeeds but len is zero, happens when process has gone away // sysctl succeeds but len is zero, happens when process has gone away
if (len == 0) { if (len == 0) {
NoSuchProcess(); NoSuchProcess("");
return -1; return -1;
} }
return 0; return 0;
@ -255,27 +346,16 @@ psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
/* /*
* A thin wrapper around proc_pidinfo() * A wrapper around proc_pidinfo().
* Returns 0 on failure (and Python exception gets already set).
*/ */
int int
psutil_proc_pidinfo(long pid, int flavor, void *pti, int size) psutil_proc_pidinfo(long pid, int flavor, uint64_t arg, void *pti, int size) {
{ errno = 0;
int ret = proc_pidinfo((int)pid, flavor, 0, pti, size); int ret = proc_pidinfo((int)pid, flavor, arg, pti, size);
if (ret == 0) { if ((ret <= 0) || ((unsigned long)ret < sizeof(pti))) {
if (! psutil_pid_exists(pid)) { psutil_raise_for_pid(pid, "proc_pidinfo()");
NoSuchProcess();
return 0;
}
else {
AccessDenied();
return 0;
}
}
else if (ret != size) {
AccessDenied();
return 0; return 0;
} }
else { return ret;
return 1;
}
} }

Просмотреть файл

@ -9,8 +9,9 @@
typedef struct kinfo_proc kinfo_proc; typedef struct kinfo_proc kinfo_proc;
int psutil_get_argmax(void); int psutil_get_argmax(void);
int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp); int psutil_get_kinfo_proc(long pid, struct kinfo_proc *kp);
int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount); int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
int psutil_pid_exists(long pid); int psutil_proc_pidinfo(
int psutil_proc_pidinfo(long pid, int flavor, void *pti, int size); long pid, int flavor, uint64_t arg, void *pti, int size);
PyObject* psutil_get_arg_list(long pid); PyObject* psutil_get_cmdline(long pid);
PyObject* psutil_get_environ(long pid);

405
third_party/python/psutil/psutil/arch/solaris/environ.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,405 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Oleksii Shevchuk.
* 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 for Process.environ().
*/
#define NEW_MIB_COMPLIANT 1
#define _STRUCTURED_PROC 1
#include <Python.h>
#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
# undef _FILE_OFFSET_BITS
# undef _LARGEFILE64_SOURCE
#endif
#include <sys/types.h>
#include <sys/procfs.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "environ.h"
#define STRING_SEARCH_BUF_SIZE 512
/*
* Open address space of specified process and return file descriptor.
* @param pid a pid of process.
* @param procfs_path a path to mounted procfs filesystem.
* @return file descriptor or -1 in case of error.
*/
static int
open_address_space(pid_t pid, const char *procfs_path) {
int fd;
char proc_path[PATH_MAX];
snprintf(proc_path, PATH_MAX, "%s/%i/as", procfs_path, pid);
fd = open(proc_path, O_RDONLY);
if (fd < 0)
PyErr_SetFromErrno(PyExc_OSError);
return fd;
}
/*
* Read chunk of data by offset to specified buffer of the same size.
* @param fd a file descriptor.
* @param offset an required offset in file.
* @param buf a buffer where to store result.
* @param buf_size a size of buffer where data will be stored.
* @return amount of bytes stored to the buffer or -1 in case of
* error.
*/
static int
read_offt(int fd, off_t offset, char *buf, size_t buf_size) {
size_t to_read = buf_size;
size_t stored = 0;
int r;
while (to_read) {
r = pread(fd, buf + stored, to_read, offset + stored);
if (r < 0)
goto error;
else if (r == 0)
break;
to_read -= r;
stored += r;
}
return stored;
error:
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
/*
* Read null-terminated string from file descriptor starting from
* specified offset.
* @param fd a file descriptor of opened address space.
* @param offset an offset in specified file descriptor.
* @return allocated null-terminated string or NULL in case of error.
*/
static char *
read_cstring_offt(int fd, off_t offset) {
int r;
int i = 0;
off_t end = offset;
size_t len;
char buf[STRING_SEARCH_BUF_SIZE];
char *result = NULL;
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
// Search end of string
for (;;) {
r = read(fd, buf, sizeof(buf));
if (r == -1) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
else if (r == 0) {
break;
}
else {
for (i=0; i<r; i++)
if (! buf[i])
goto found;
}
end += r;
}
found:
len = end + i - offset;
result = malloc(len+1);
if (! result) {
PyErr_NoMemory();
goto error;
}
if (len) {
if (read_offt(fd, offset, result, len) < 0) {
goto error;
}
}
result[len] = '\0';
return result;
error:
if (result)
free(result);
return NULL;
}
/*
* Read block of addresses by offset, dereference them one by one
* and create an array of null terminated C strings from them.
* @param fd a file descriptor of address space of interesting process.
* @param offset an offset of address block in address space.
* @param ptr_size a size of pointer. Only 4 or 8 are valid values.
* @param count amount of pointers in block.
* @return allocated array of strings dereferenced and read by offset.
* Number of elements in array are count. In case of error function
* returns NULL.
*/
static char **
read_cstrings_block(int fd, off_t offset, size_t ptr_size, size_t count) {
char **result = NULL;
char *pblock = NULL;
size_t pblock_size;
int i;
assert(ptr_size == 4 || ptr_size == 8);
if (!count)
goto error;
pblock_size = ptr_size * count;
pblock = malloc(pblock_size);
if (! pblock) {
PyErr_NoMemory();
goto error;
}
if (read_offt(fd, offset, pblock, pblock_size) != pblock_size)
goto error;
result = (char **) calloc(count, sizeof(char *));
if (! result) {
PyErr_NoMemory();
goto error;
}
for (i=0; i<count; i++) {
result[i] = read_cstring_offt(
fd, (ptr_size == 4?
((uint32_t *) pblock)[i]:
((uint64_t *) pblock)[i]));
if (!result[i])
goto error;
}
free(pblock);
return result;
error:
if (result)
psutil_free_cstrings_array(result, i);
if (pblock)
free(pblock);
return NULL;
}
/*
* Check that caller process can extract proper values from psinfo_t
* structure.
* @param info a pointer to process info (psinfo_t) structure of the
* interesting process.
* @return 1 in case if caller process can extract proper values from
* psinfo_t structure, or 0 otherwise.
*/
static inline int
is_ptr_dereference_possible(psinfo_t info) {
#if !defined(_LP64)
return info.pr_dmodel == PR_MODEL_ILP32;
#else
return 1;
#endif
}
/*
* Return pointer size according to psinfo_t structure
* @param info a ponter to process info (psinfo_t) structure of the
* interesting process.
* @return pointer size (4 or 8).
*/
static inline int
ptr_size_by_psinfo(psinfo_t info) {
return info.pr_dmodel == PR_MODEL_ILP32? 4 : 8;
}
/*
* Count amount of pointers in a block which ends with NULL.
* @param fd a discriptor of /proc/PID/as special file.
* @param offt an offset of block of pointers at the file.
* @param ptr_size a pointer size (allowed values: {4, 8}).
* @return amount of non-NULL pointers or -1 in case of error.
*/
static int
search_pointers_vector_size_offt(int fd, off_t offt, size_t ptr_size) {
int count = 0;
int r;
char buf[8];
static const char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
assert(ptr_size == 4 || ptr_size == 8);
if (lseek(fd, offt, SEEK_SET) == (off_t)-1)
goto error;
for (;; count ++) {
r = read(fd, buf, ptr_size);
if (r < 0)
goto error;
if (r == 0)
break;
if (r != ptr_size) {
PyErr_SetString(
PyExc_RuntimeError, "pointer block is truncated");
return -1;
}
if (! memcmp(buf, zeros, ptr_size))
break;
}
return count;
error:
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
/*
* Derefence and read array of strings by psinfo_t.pr_argv pointer from
* remote process.
* @param info a ponter to process info (psinfo_t) structure of the
* interesting process
* @param procfs_path a cstring with path to mounted procfs filesystem.
* @param count a pointer to variable where to store amount of elements in
* returned array. In case of error value of variable will not be
changed.
* @return allocated array of cstrings or NULL in case of error.
*/
char **
psutil_read_raw_args(psinfo_t info, const char *procfs_path, size_t *count) {
int as;
char **result;
if (! is_ptr_dereference_possible(info)) {
PyErr_SetString(
PyExc_NotImplementedError,
"can't get env of a 64 bit process from a 32 bit process");
return NULL;
}
if (! (info.pr_argv && info.pr_argc)) {
PyErr_SetString(
PyExc_RuntimeError, "process doesn't have arguments block");
return NULL;
}
as = open_address_space(info.pr_pid, procfs_path);
if (as < 0)
return NULL;
result = read_cstrings_block(
as, info.pr_argv, ptr_size_by_psinfo(info), info.pr_argc
);
if (result && count)
*count = info.pr_argc;
close(as);
return result;
}
/*
* Dereference and read array of strings by psinfo_t.pr_envp pointer
* from remote process.
* @param info a ponter to process info (psinfo_t) structure of the
* interesting process.
* @param procfs_path a cstring with path to mounted procfs filesystem.
* @param count a pointer to variable where to store amount of elements in
* returned array. In case of error value of variable will not be
* changed. To detect special case (described later) variable should be
* initialized by -1 or other negative value.
* @return allocated array of cstrings or NULL in case of error.
* Special case: count set to 0, return NULL.
* Special case means there is no error acquired, but no data
* retrieved.
* Special case exists because the nature of the process. From the
* beginning it's not clean how many pointers in envp array. Also
* situation when environment is empty is common for kernel processes.
*/
char **
psutil_read_raw_env(psinfo_t info, const char *procfs_path, ssize_t *count) {
int as;
int env_count;
int ptr_size;
char **result = NULL;
if (! is_ptr_dereference_possible(info)) {
PyErr_SetString(
PyExc_NotImplementedError,
"can't get env of a 64 bit process from a 32 bit process");
return NULL;
}
as = open_address_space(info.pr_pid, procfs_path);
if (as < 0)
return NULL;
ptr_size = ptr_size_by_psinfo(info);
env_count = search_pointers_vector_size_offt(
as, info.pr_envp, ptr_size);
if (env_count >= 0 && count)
*count = env_count;
if (env_count > 0)
result = read_cstrings_block(
as, info.pr_envp, ptr_size, env_count);
close(as);
return result;
}
/*
* Free array of cstrings.
* @param array an array of cstrings returned by psutil_read_raw_env,
* psutil_read_raw_args or any other function.
* @param count a count of strings in the passed array
*/
void
psutil_free_cstrings_array(char **array, size_t count) {
int i;
if (!array)
return;
for (i=0; i<count; i++) {
if (array[i]) {
free(array[i]);
}
}
free(array);
}

19
third_party/python/psutil/psutil/arch/solaris/environ.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Oleksii Shevchuk.
* All rights reserved. Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
#ifndef PROCESS_AS_UTILS_H
#define PROCESS_AS_UTILS_H
char **
psutil_read_raw_args(psinfo_t info, const char *procfs_path, size_t *count);
char **
psutil_read_raw_env(psinfo_t info, const char *procfs_path, ssize_t *count);
void
psutil_free_cstrings_array(char **array, size_t count);
#endif // PROCESS_AS_UTILS_H

124
third_party/python/psutil/psutil/arch/solaris/v10/ifaddrs.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,124 @@
/* Refrences:
* https://lists.samba.org/archive/samba-technical/2009-February/063079.html
* http://stackoverflow.com/questions/4139405/#4139811
* https://github.com/steve-o/openpgm/blob/master/openpgm/pgm/getifaddrs.c
*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include "ifaddrs.h"
#define MAX(x,y) ((x)>(y)?(x):(y))
#define SIZE(p) MAX((p).ss_len,sizeof(p))
static struct sockaddr *
sa_dup (struct sockaddr_storage *sa1)
{
struct sockaddr *sa2;
size_t sz = sizeof(struct sockaddr_storage);
sa2 = (struct sockaddr *) calloc(1,sz);
memcpy(sa2,sa1,sz);
return(sa2);
}
void freeifaddrs (struct ifaddrs *ifp)
{
if (NULL == ifp) return;
free(ifp->ifa_name);
free(ifp->ifa_addr);
free(ifp->ifa_netmask);
free(ifp->ifa_dstaddr);
freeifaddrs(ifp->ifa_next);
free(ifp);
}
int getifaddrs (struct ifaddrs **ifap)
{
int sd = -1;
char *ccp, *ecp;
struct lifconf ifc;
struct lifreq *ifr;
struct lifnum lifn;
struct ifaddrs *cifa = NULL; /* current */
struct ifaddrs *pifa = NULL; /* previous */
const size_t IFREQSZ = sizeof(struct lifreq);
sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0)
goto error;
ifc.lifc_buf = NULL;
*ifap = NULL;
/* find how much memory to allocate for the SIOCGLIFCONF call */
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = 0;
if (ioctl(sd, SIOCGLIFNUM, &lifn) < 0)
goto error;
/* Sun and Apple code likes to pad the interface count here in case interfaces
* are coming up between calls */
lifn.lifn_count += 4;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_len = lifn.lifn_count * sizeof(struct lifreq);
ifc.lifc_buf = calloc(1, ifc.lifc_len);
if (ioctl(sd, SIOCGLIFCONF, &ifc) < 0)
goto error;
ccp = (char *)ifc.lifc_req;
ecp = ccp + ifc.lifc_len;
while (ccp < ecp) {
ifr = (struct lifreq *) ccp;
cifa = (struct ifaddrs *) calloc(1, sizeof(struct ifaddrs));
cifa->ifa_next = NULL;
cifa->ifa_name = strdup(ifr->lifr_name);
if (pifa == NULL) *ifap = cifa; /* first one */
else pifa->ifa_next = cifa;
if (ioctl(sd, SIOCGLIFADDR, ifr, IFREQSZ) < 0)
goto error;
cifa->ifa_addr = sa_dup(&ifr->lifr_addr);
if (ioctl(sd, SIOCGLIFNETMASK, ifr, IFREQSZ) < 0)
goto error;
cifa->ifa_netmask = sa_dup(&ifr->lifr_addr);
cifa->ifa_flags = 0;
cifa->ifa_dstaddr = NULL;
if (0 == ioctl(sd, SIOCGLIFFLAGS, ifr)) /* optional */
cifa->ifa_flags = ifr->lifr_flags;
if (ioctl(sd, SIOCGLIFDSTADDR, ifr, IFREQSZ) < 0) {
if (0 == ioctl(sd, SIOCGLIFBRDADDR, ifr, IFREQSZ))
cifa->ifa_dstaddr = sa_dup(&ifr->lifr_addr);
}
else cifa->ifa_dstaddr = sa_dup(&ifr->lifr_addr);
pifa = cifa;
ccp += IFREQSZ;
}
free(ifc.lifc_buf);
close(sd);
return 0;
error:
if (ifc.lifc_buf != NULL)
free(ifc.lifc_buf);
if (sd != -1)
close(sd);
return (-1);
}

26
third_party/python/psutil/psutil/arch/solaris/v10/ifaddrs.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,26 @@
/* Reference: https://lists.samba.org/archive/samba-technical/2009-February/063079.html */
#ifndef __IFADDRS_H__
#define __IFADDRS_H__
#include <sys/socket.h>
#include <net/if.h>
#undef ifa_dstaddr
#undef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
};
extern int getifaddrs(struct ifaddrs **);
extern void freeifaddrs(struct ifaddrs *);
#endif

Просмотреть файл

@ -1,41 +1,46 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Jeff Tang. 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 "inet_ntop.h" #include "inet_ntop.h"
// From: https://memset.wordpress.com/2010/10/09/inet_ntop-for-win32/ // From: https://memset.wordpress.com/2010/10/09/inet_ntop-for-win32/
PCSTR PCSTR WSAAPI
WSAAPI inet_ntop(__in INT family,
inet_ntop( __in PVOID pAddr,
__in INT Family, __out_ecount(StringBufSize) PSTR pStringBuf,
__in PVOID pAddr, __in size_t StringBufSize) {
__out_ecount(StringBufSize) PSTR pStringBuf,
__in size_t StringBufSize
)
{
DWORD dwAddressLength = 0; DWORD dwAddressLength = 0;
struct sockaddr_storage srcaddr; struct sockaddr_storage srcaddr;
struct sockaddr_in *srcaddr4 = (struct sockaddr_in*) &srcaddr; struct sockaddr_in *srcaddr4 = (struct sockaddr_in*) &srcaddr;
struct sockaddr_in6 *srcaddr6 = (struct sockaddr_in6*) &srcaddr; struct sockaddr_in6 *srcaddr6 = (struct sockaddr_in6*) &srcaddr;
memset(&srcaddr, 0, sizeof(struct sockaddr_storage)); memset(&srcaddr, 0, sizeof(struct sockaddr_storage));
srcaddr.ss_family = Family; srcaddr.ss_family = family;
if (Family == AF_INET) if (family == AF_INET) {
{
dwAddressLength = sizeof(struct sockaddr_in); dwAddressLength = sizeof(struct sockaddr_in);
memcpy(&(srcaddr4->sin_addr), pAddr, sizeof(struct in_addr)); memcpy(&(srcaddr4->sin_addr), pAddr, sizeof(struct in_addr));
} else if (Family == AF_INET6) }
{ else if (family == AF_INET6) {
dwAddressLength = sizeof(struct sockaddr_in6); dwAddressLength = sizeof(struct sockaddr_in6);
memcpy(&(srcaddr6->sin6_addr), pAddr, sizeof(struct in6_addr)); memcpy(&(srcaddr6->sin6_addr), pAddr, sizeof(struct in6_addr));
} else { }
else {
PyErr_SetString(PyExc_ValueError, "invalid family");
return NULL; return NULL;
} }
if (WSAAddressToString((LPSOCKADDR) &srcaddr, if (WSAAddressToString((LPSOCKADDR) &srcaddr,
dwAddressLength, dwAddressLength,
0, 0,
pStringBuf, pStringBuf,
(LPDWORD) &StringBufSize) != 0) { (LPDWORD) &StringBufSize) != 0) {
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
return NULL; return NULL;
} }
return pStringBuf; return pStringBuf;
} }

Просмотреть файл

@ -1,10 +1,15 @@
/*
* Copyright (c) 2009, Giampaolo Rodola', Jeff Tang. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <ws2tcpip.h> #include <ws2tcpip.h>
PCSTR PCSTR WSAAPI
WSAAPI
inet_ntop( inet_ntop(
__in INT Family, __in INT Family,
__in PVOID pAddr, __in PVOID pAddr,
__out_ecount(StringBufSize) PSTR pStringBuf, __out_ecount(StringBufSize) PSTR pStringBuf,
__in size_t StringBufSize __in size_t StringBufSize
); );

Просмотреть файл

@ -7,6 +7,106 @@
#define __NTEXTAPI_H__ #define __NTEXTAPI_H__
#include <winternl.h> #include <winternl.h>
typedef struct {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
typedef struct {
LARGE_INTEGER IdleProcessTime;
LARGE_INTEGER IoReadTransferCount;
LARGE_INTEGER IoWriteTransferCount;
LARGE_INTEGER IoOtherTransferCount;
ULONG IoReadOperationCount;
ULONG IoWriteOperationCount;
ULONG IoOtherOperationCount;
ULONG AvailablePages;
ULONG CommittedPages;
ULONG CommitLimit;
ULONG PeakCommitment;
ULONG PageFaultCount;
ULONG CopyOnWriteCount;
ULONG TransitionCount;
ULONG CacheTransitionCount;
ULONG DemandZeroCount;
ULONG PageReadCount;
ULONG PageReadIoCount;
ULONG CacheReadCount;
ULONG CacheIoCount;
ULONG DirtyPagesWriteCount;
ULONG DirtyWriteIoCount;
ULONG MappedPagesWriteCount;
ULONG MappedWriteIoCount;
ULONG PagedPoolPages;
ULONG NonPagedPoolPages;
ULONG PagedPoolAllocs;
ULONG PagedPoolFrees;
ULONG NonPagedPoolAllocs;
ULONG NonPagedPoolFrees;
ULONG FreeSystemPtes;
ULONG ResidentSystemCodePage;
ULONG TotalSystemDriverPages;
ULONG TotalSystemCodePages;
ULONG NonPagedPoolLookasideHits;
ULONG PagedPoolLookasideHits;
ULONG AvailablePagedPoolPages;
ULONG ResidentSystemCachePage;
ULONG ResidentPagedPoolPage;
ULONG ResidentSystemDriverPage;
ULONG CcFastReadNoWait;
ULONG CcFastReadWait;
ULONG CcFastReadResourceMiss;
ULONG CcFastReadNotPossible;
ULONG CcFastMdlReadNoWait;
ULONG CcFastMdlReadWait;
ULONG CcFastMdlReadResourceMiss;
ULONG CcFastMdlReadNotPossible;
ULONG CcMapDataNoWait;
ULONG CcMapDataWait;
ULONG CcMapDataNoWaitMiss;
ULONG CcMapDataWaitMiss;
ULONG CcPinMappedDataCount;
ULONG CcPinReadNoWait;
ULONG CcPinReadWait;
ULONG CcPinReadNoWaitMiss;
ULONG CcPinReadWaitMiss;
ULONG CcCopyReadNoWait;
ULONG CcCopyReadWait;
ULONG CcCopyReadNoWaitMiss;
ULONG CcCopyReadWaitMiss;
ULONG CcMdlReadNoWait;
ULONG CcMdlReadWait;
ULONG CcMdlReadNoWaitMiss;
ULONG CcMdlReadWaitMiss;
ULONG CcReadAheadIos;
ULONG CcLazyWriteIos;
ULONG CcLazyWritePages;
ULONG CcDataFlushes;
ULONG CcDataPages;
ULONG ContextSwitches;
ULONG FirstLevelTbFills;
ULONG SecondLevelTbFills;
ULONG SystemCalls;
} _SYSTEM_PERFORMANCE_INFORMATION;
typedef struct {
ULONG ContextSwitches;
ULONG DpcCount;
ULONG DpcRate;
ULONG TimeIncrement;
ULONG DpcBypassCount;
ULONG ApcBypassCount;
} _SYSTEM_INTERRUPT_INFORMATION;
typedef enum _KTHREAD_STATE { typedef enum _KTHREAD_STATE {
Initialized, Initialized,
Ready, Ready,
@ -20,6 +120,7 @@ typedef enum _KTHREAD_STATE {
MaximumThreadState MaximumThreadState
} KTHREAD_STATE, *PKTHREAD_STATE; } KTHREAD_STATE, *PKTHREAD_STATE;
typedef enum _KWAIT_REASON { typedef enum _KWAIT_REASON {
Executive = 0, Executive = 0,
FreePage = 1, FreePage = 1,
@ -61,12 +162,16 @@ typedef enum _KWAIT_REASON {
MaximumWaitReason = 37 MaximumWaitReason = 37
} KWAIT_REASON, *PKWAIT_REASON; } KWAIT_REASON, *PKWAIT_REASON;
typedef struct _CLIENT_ID {
typedef struct _CLIENT_ID2 {
HANDLE UniqueProcess; HANDLE UniqueProcess;
HANDLE UniqueThread; HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID; } CLIENT_ID2, *PCLIENT_ID2;
typedef struct _SYSTEM_THREAD_INFORMATION { #define CLIENT_ID CLIENT_ID2
#define PCLIENT_ID PCLIENT_ID2
typedef struct _SYSTEM_THREAD_INFORMATION2 {
LARGE_INTEGER KernelTime; LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime; LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime; LARGE_INTEGER CreateTime;
@ -78,10 +183,14 @@ typedef struct _SYSTEM_THREAD_INFORMATION {
ULONG ContextSwitches; ULONG ContextSwitches;
ULONG ThreadState; ULONG ThreadState;
KWAIT_REASON WaitReason; KWAIT_REASON WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; } SYSTEM_THREAD_INFORMATION2, *PSYSTEM_THREAD_INFORMATION2;
#define SYSTEM_THREAD_INFORMATION SYSTEM_THREAD_INFORMATION2
#define PSYSTEM_THREAD_INFORMATION PSYSTEM_THREAD_INFORMATION2
typedef struct _TEB *PTEB; typedef struct _TEB *PTEB;
// private // private
typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION { typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION {
SYSTEM_THREAD_INFORMATION ThreadInfo; SYSTEM_THREAD_INFORMATION ThreadInfo;
@ -94,6 +203,7 @@ typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION {
ULONG_PTR Reserved4; ULONG_PTR Reserved4;
} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION; } SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION2 { typedef struct _SYSTEM_PROCESS_INFORMATION2 {
ULONG NextEntryOffset; ULONG NextEntryOffset;
ULONG NumberOfThreads; ULONG NumberOfThreads;
@ -151,6 +261,7 @@ typedef struct _WINSTATION_INFO {
FILETIME CurrentTime; FILETIME CurrentTime;
} WINSTATION_INFO, *PWINSTATION_INFO; } WINSTATION_INFO, *PWINSTATION_INFO;
typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW) typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
(HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG); (HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
@ -162,6 +273,7 @@ typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)
*/ */
typedef LONG NTSTATUS; typedef LONG NTSTATUS;
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)( typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
HANDLE ProcessHandle, HANDLE ProcessHandle,
DWORD ProcessInformationClass, DWORD ProcessInformationClass,
@ -170,6 +282,7 @@ typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
PDWORD ReturnLength PDWORD ReturnLength
); );
typedef NTSTATUS (NTAPI *_NtSetInformationProcess)( typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
HANDLE ProcessHandle, HANDLE ProcessHandle,
DWORD ProcessInformationClass, DWORD ProcessInformationClass,
@ -186,7 +299,7 @@ typedef enum _PROCESSINFOCLASS2 {
ProcessTimes, ProcessTimes,
ProcessBasePriority, ProcessBasePriority,
ProcessRaisePriority, ProcessRaisePriority,
ProcessDebugPort, _ProcessDebugPort,
ProcessExceptionPort, ProcessExceptionPort,
ProcessAccessToken, ProcessAccessToken,
ProcessLdtInformation, ProcessLdtInformation,
@ -207,9 +320,9 @@ typedef enum _PROCESSINFOCLASS2 {
ProcessForegroundInformation, ProcessForegroundInformation,
_ProcessWow64Information, _ProcessWow64Information,
/* added after XP+ */ /* added after XP+ */
ProcessImageFileName, _ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled, ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination, _ProcessBreakOnTermination,
ProcessDebugObjectHandle, ProcessDebugObjectHandle,
ProcessDebugFlags, ProcessDebugFlags,
ProcessHandleTracing, ProcessHandleTracing,
@ -221,8 +334,12 @@ typedef enum _PROCESSINFOCLASS2 {
MaxProcessInfoClass MaxProcessInfoClass
} PROCESSINFOCLASS2; } PROCESSINFOCLASS2;
#define PROCESSINFOCLASS PROCESSINFOCLASS2 #define PROCESSINFOCLASS PROCESSINFOCLASS2
#define ProcessBasicInformation _ProcessBasicInformation #define ProcessBasicInformation _ProcessBasicInformation
#define ProcessWow64Information _ProcessWow64Information #define ProcessWow64Information _ProcessWow64Information
#define ProcessDebugPort _ProcessDebugPort
#define ProcessImageFileName _ProcessImageFileName
#define ProcessBreakOnTermination _ProcessBreakOnTermination
#endif // __NTEXTAPI_H__ #endif // __NTEXTAPI_H__

Просмотреть файл

@ -5,6 +5,7 @@
* *
*/ */
#include "process_handles.h" #include "process_handles.h"
#include "../../_psutil_common.h"
static _NtQuerySystemInformation __NtQuerySystemInformation = NULL; static _NtQuerySystemInformation __NtQuerySystemInformation = NULL;
static _NtQueryObject __NtQueryObject = NULL; static _NtQueryObject __NtQueryObject = NULL;
@ -19,18 +20,16 @@ HANDLE g_hThread = NULL;
PUNICODE_STRING g_pNameBuffer = NULL; PUNICODE_STRING g_pNameBuffer = NULL;
ULONG g_dwSize = 0; ULONG g_dwSize = 0;
ULONG g_dwLength = 0; ULONG g_dwLength = 0;
PVOID g_fiber = NULL;
PVOID PVOID
GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName) GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName) {
{
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName); return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
} }
PyObject * PyObject *
psutil_get_open_files(long dwPid, HANDLE hProcess) psutil_get_open_files(long dwPid, HANDLE hProcess) {
{
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
@ -44,9 +43,9 @@ psutil_get_open_files(long dwPid, HANDLE hProcess)
return psutil_get_open_files_getmappedfilename(dwPid, hProcess); return psutil_get_open_files_getmappedfilename(dwPid, hProcess);
} }
VOID VOID
psutil_get_open_files_init(BOOL threaded) psutil_get_open_files_init(BOOL threaded) {
{
if (g_initialized == TRUE) if (g_initialized == TRUE)
return; return;
@ -65,9 +64,9 @@ psutil_get_open_files_init(BOOL threaded)
g_initialized = TRUE; g_initialized = TRUE;
} }
PyObject * PyObject *
psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess) psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess) {
{
NTSTATUS status; NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL; PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
DWORD dwInfoSize = 0x10000; DWORD dwInfoSize = 0x10000;
@ -75,9 +74,9 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX hHandle = NULL; PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX hHandle = NULL;
DWORD i = 0; DWORD i = 0;
BOOLEAN error = FALSE; BOOLEAN error = FALSE;
PyObject* pyListFiles = NULL;
PyObject* pyFilePath = NULL;
DWORD dwWait = 0; DWORD dwWait = 0;
PyObject* py_retlist = NULL;
PyObject* py_path = NULL;
if (g_initialized == FALSE) if (g_initialized == FALSE)
psutil_get_open_files_init(TRUE); psutil_get_open_files_init(TRUE);
@ -98,8 +97,8 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
} }
// Py_BuildValue raises an exception if NULL is returned // Py_BuildValue raises an exception if NULL is returned
pyListFiles = PyList_New(0); py_retlist = PyList_New(0);
if (pyListFiles == NULL) { if (py_retlist == NULL) {
error = TRUE; error = TRUE;
goto cleanup; goto cleanup;
} }
@ -139,8 +138,7 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
hHandle = &pHandleInfo->Handles[i]; hHandle = &pHandleInfo->Handles[i];
// Check if this hHandle belongs to the PID the user specified. // Check if this hHandle belongs to the PID the user specified.
if (hHandle->UniqueProcessId != (HANDLE)dwPid || if (hHandle->UniqueProcessId != (HANDLE)dwPid)
hHandle->ObjectTypeIndex != HANDLE_TYPE_FILE)
goto loop_cleanup; goto loop_cleanup;
if (!DuplicateHandle(hProcess, if (!DuplicateHandle(hProcess,
@ -208,9 +206,9 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
g_pNameBuffer->Buffer); g_pNameBuffer->Buffer);
*/ */
pyFilePath = PyUnicode_FromWideChar(g_pNameBuffer->Buffer, py_path = PyUnicode_FromWideChar(g_pNameBuffer->Buffer,
g_pNameBuffer->Length/2); g_pNameBuffer->Length/2);
if (pyFilePath == NULL) { if (py_path == NULL) {
/* /*
printf("[%d] PyUnicode_FromWideChar (%#x): %#x \n", printf("[%d] PyUnicode_FromWideChar (%#x): %#x \n",
dwPid, dwPid,
@ -221,7 +219,7 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
goto loop_cleanup; goto loop_cleanup;
} }
if (PyList_Append(pyListFiles, pyFilePath)) { if (PyList_Append(py_retlist, py_path)) {
/* /*
printf("[%d] PyList_Append (%#x): %#x \n", printf("[%d] PyList_Append (%#x): %#x \n",
dwPid, dwPid,
@ -234,8 +232,8 @@ psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess)
} }
loop_cleanup: loop_cleanup:
Py_XDECREF(pyFilePath); Py_XDECREF(py_path);
pyFilePath = NULL; py_path = NULL;
if (g_pNameBuffer != NULL) if (g_pNameBuffer != NULL)
HeapFree(GetProcessHeap(), 0, g_pNameBuffer); HeapFree(GetProcessHeap(), 0, g_pNameBuffer);
@ -264,27 +262,28 @@ cleanup:
pHandleInfo = NULL; pHandleInfo = NULL;
if (error) { if (error) {
Py_XDECREF(pyListFiles); Py_XDECREF(py_retlist);
pyListFiles = NULL; py_retlist = NULL;
} }
LeaveCriticalSection(&g_cs); LeaveCriticalSection(&g_cs);
return pyListFiles; return py_retlist;
} }
DWORD DWORD
psutil_NtQueryObject() psutil_NtQueryObject() {
{
DWORD dwWait = 0; DWORD dwWait = 0;
if (g_hThread == NULL) if (g_hThread == NULL)
g_hThread = CreateThread(NULL, g_hThread = CreateThread(
0, NULL,
(LPTHREAD_START_ROUTINE)psutil_NtQueryObjectThread, 0,
NULL, psutil_NtQueryObjectThread,
0, NULL,
NULL); 0,
NULL);
if (g_hThread == NULL) if (g_hThread == NULL)
return GetLastError(); return GetLastError();
@ -301,24 +300,15 @@ psutil_NtQueryObject()
WaitForSingleObject(g_hThread, INFINITE); WaitForSingleObject(g_hThread, INFINITE);
CloseHandle(g_hThread); CloseHandle(g_hThread);
// Cleanup Fiber
if (g_fiber != NULL)
DeleteFiber(g_fiber);
g_fiber = NULL;
g_hThread = NULL; g_hThread = NULL;
} }
return dwWait; return dwWait;
} }
void
psutil_NtQueryObjectThread()
{
// Prevent the thread stack from leaking when this
// thread gets terminated due to NTQueryObject hanging
g_fiber = ConvertThreadToFiber(NULL);
DWORD WINAPI
psutil_NtQueryObjectThread(LPVOID lpvParam) {
// Loop infinitely waiting for work // Loop infinitely waiting for work
while (TRUE) { while (TRUE) {
WaitForSingleObject(g_hEvtStart, INFINITE); WaitForSingleObject(g_hEvtStart, INFINITE);
@ -332,9 +322,9 @@ psutil_NtQueryObjectThread()
} }
} }
PyObject * PyObject *
psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess) psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess) {
{
NTSTATUS status; NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL; PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
DWORD dwInfoSize = 0x10000; DWORD dwInfoSize = 0x10000;
@ -344,8 +334,8 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
HANDLE hMap = NULL; HANDLE hMap = NULL;
DWORD i = 0; DWORD i = 0;
BOOLEAN error = FALSE; BOOLEAN error = FALSE;
PyObject* pyListFiles = NULL; PyObject* py_retlist = NULL;
PyObject* pyFilePath = NULL; PyObject* py_path = NULL;
ULONG dwSize = 0; ULONG dwSize = 0;
LPVOID pMem = NULL; LPVOID pMem = NULL;
TCHAR pszFilename[MAX_PATH+1]; TCHAR pszFilename[MAX_PATH+1];
@ -360,8 +350,8 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
} }
// Py_BuildValue raises an exception if NULL is returned // Py_BuildValue raises an exception if NULL is returned
pyListFiles = PyList_New(0); py_retlist = PyList_New(0);
if (pyListFiles == NULL) { if (py_retlist == NULL) {
error = TRUE; error = TRUE;
goto cleanup; goto cleanup;
} }
@ -401,8 +391,7 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
hHandle = &pHandleInfo->Handles[i]; hHandle = &pHandleInfo->Handles[i];
// Check if this hHandle belongs to the PID the user specified. // Check if this hHandle belongs to the PID the user specified.
if (hHandle->UniqueProcessId != (HANDLE)dwPid || if (hHandle->UniqueProcessId != (HANDLE)dwPid)
hHandle->ObjectTypeIndex != HANDLE_TYPE_FILE)
goto loop_cleanup; goto loop_cleanup;
if (!DuplicateHandle(hProcess, if (!DuplicateHandle(hProcess,
@ -445,7 +434,8 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
goto loop_cleanup; goto loop_cleanup;
} }
dwSize = GetMappedFileName(GetCurrentProcess(), pMem, pszFilename, MAX_PATH); dwSize = GetMappedFileName(
GetCurrentProcess(), pMem, pszFilename, MAX_PATH);
if (dwSize == 0) { if (dwSize == 0) {
/* /*
printf("[%d] GetMappedFileName (%#x): %#x \n", printf("[%d] GetMappedFileName (%#x): %#x \n",
@ -465,8 +455,8 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
pszFilename); pszFilename);
*/ */
pyFilePath = PyUnicode_FromWideChar(pszFilename, dwSize); py_path = PyUnicode_FromWideChar(pszFilename, dwSize);
if (pyFilePath == NULL) { if (py_path == NULL) {
/* /*
printf("[%d] PyUnicode_FromStringAndSize (%#x): %#x \n", printf("[%d] PyUnicode_FromStringAndSize (%#x): %#x \n",
dwPid, dwPid,
@ -477,7 +467,7 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
goto loop_cleanup; goto loop_cleanup;
} }
if (PyList_Append(pyListFiles, pyFilePath)) { if (PyList_Append(py_retlist, py_path)) {
/* /*
printf("[%d] PyList_Append (%#x): %#x \n", printf("[%d] PyList_Append (%#x): %#x \n",
dwPid, dwPid,
@ -489,8 +479,8 @@ psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess)
} }
loop_cleanup: loop_cleanup:
Py_XDECREF(pyFilePath); Py_XDECREF(py_path);
pyFilePath = NULL; py_path = NULL;
if (pMem != NULL) if (pMem != NULL)
UnmapViewOfFile(pMem); UnmapViewOfFile(pMem);
@ -525,9 +515,9 @@ cleanup:
pHandleInfo = NULL; pHandleInfo = NULL;
if (error) { if (error) {
Py_XDECREF(pyListFiles); Py_XDECREF(py_retlist);
pyListFiles = NULL; py_retlist = NULL;
} }
return pyListFiles; return py_retlist;
} }

Просмотреть файл

@ -48,8 +48,7 @@ typedef NTSTATUS (NTAPI *_NtQueryObject)(
// Undocumented FILE_INFORMATION_CLASS: FileNameInformation // Undocumented FILE_INFORMATION_CLASS: FileNameInformation
static const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64; static const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX {
{
PVOID Object; PVOID Object;
HANDLE UniqueProcessId; HANDLE UniqueProcessId;
HANDLE HandleValue; HANDLE HandleValue;
@ -60,8 +59,7 @@ typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
ULONG Reserved; ULONG Reserved;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX; } SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
typedef struct _SYSTEM_HANDLE_INFORMATION_EX typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
{
ULONG_PTR NumberOfHandles; ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved; ULONG_PTR Reserved;
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
@ -108,6 +106,6 @@ PyObject* psutil_get_open_files(long pid, HANDLE processHandle);
PyObject* psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess); PyObject* psutil_get_open_files_ntqueryobject(long dwPid, HANDLE hProcess);
PyObject* psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess); PyObject* psutil_get_open_files_getmappedfilename(long dwPid, HANDLE hProcess);
DWORD psutil_NtQueryObject(void); DWORD psutil_NtQueryObject(void);
void psutil_NtQueryObjectThread(void); DWORD WINAPI psutil_NtQueryObjectThread(LPVOID lpvParam);
#endif // __PROCESS_HANDLES_H__ #endif // __PROCESS_HANDLES_H__

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -12,15 +12,23 @@
#include "security.h" #include "security.h"
#include "ntextapi.h" #include "ntextapi.h"
#define HANDLE_TO_PYNUM(handle) PyLong_FromUnsignedLong((unsigned long) handle)
#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj))
DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs); DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
HANDLE psutil_handle_from_pid(DWORD pid); HANDLE psutil_handle_from_pid(DWORD pid);
HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess); HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
int psutil_handlep_is_running(HANDLE hProcess);
int psutil_pid_in_proclist(DWORD pid);
int psutil_pid_is_running(DWORD pid); int psutil_pid_is_running(DWORD pid);
PVOID psutil_get_peb_address(HANDLE ProcessHandle);
PyObject* psutil_get_arg_list(long pid);
int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess, int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
PVOID *retBuffer); PVOID *retBuffer);
int psutil_assert_pid_exists(DWORD pid, char *err);
int psutil_assert_pid_not_exists(DWORD pid, char *err);
PyObject* psutil_get_cmdline(long pid);
PyObject* psutil_get_cwd(long pid);
PyObject* psutil_get_environ(long pid);
#endif #endif

Просмотреть файл

@ -108,8 +108,7 @@ psutil_has_system_privilege(HANDLE hProcess) {
BOOL BOOL
psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege) psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege) {
{
TOKEN_PRIVILEGES tp; TOKEN_PRIVILEGES tp;
LUID luid; LUID luid;
TOKEN_PRIVILEGES tpPrevious; TOKEN_PRIVILEGES tpPrevious;
@ -159,8 +158,7 @@ psutil_set_privilege(HANDLE hToken, LPCTSTR Privilege, BOOL bEnablePrivilege)
int int
psutil_set_se_debug() psutil_set_se_debug() {
{
HANDLE hToken; HANDLE hToken;
if (! OpenThreadToken(GetCurrentThread(), if (! OpenThreadToken(GetCurrentThread(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
@ -198,8 +196,7 @@ psutil_set_se_debug()
int int
psutil_unset_se_debug() psutil_unset_se_debug() {
{
HANDLE hToken; HANDLE hToken;
if (! OpenThreadToken(GetCurrentThread(), if (! OpenThreadToken(GetCurrentThread(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

485
third_party/python/psutil/psutil/arch/windows/services.c поставляемый Normal file
Просмотреть файл

@ -0,0 +1,485 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
#include <windows.h>
#include <Winsvc.h>
#include "services.h"
#include "../../_psutil_common.h"
// ==================================================================
// utils
// ==================================================================
SC_HANDLE
psutil_get_service_handler(char *service_name, DWORD scm_access, DWORD access)
{
ENUM_SERVICE_STATUS_PROCESSW *lpService = NULL;
SC_HANDLE sc = NULL;
SC_HANDLE hService = NULL;
sc = OpenSCManager(NULL, NULL, scm_access);
if (sc == NULL) {
PyErr_SetFromWindowsErr(0);
return NULL;
}
hService = OpenService(sc, service_name, access);
if (hService == NULL) {
CloseServiceHandle(sc);
PyErr_SetFromWindowsErr(0);
return NULL;
}
CloseServiceHandle(sc);
return hService;
}
// XXX - expose these as constants?
static const char *
get_startup_string(DWORD startup) {
switch (startup) {
case SERVICE_AUTO_START:
return "automatic";
case SERVICE_DEMAND_START:
return "manual";
case SERVICE_DISABLED:
return "disabled";
/*
// drivers only (since we use EnumServicesStatusEx() with
// SERVICE_WIN32)
case SERVICE_BOOT_START:
return "boot-start";
case SERVICE_SYSTEM_START:
return "system-start";
*/
default:
return "unknown";
}
}
// XXX - expose these as constants?
static const char *
get_state_string(DWORD state) {
switch (state) {
case SERVICE_RUNNING:
return "running";
case SERVICE_PAUSED:
return "paused";
case SERVICE_START_PENDING:
return "start_pending";
case SERVICE_PAUSE_PENDING:
return "pause_pending";
case SERVICE_CONTINUE_PENDING:
return "continue_pending";
case SERVICE_STOP_PENDING:
return "stop_pending";
case SERVICE_STOPPED:
return "stopped";
default:
return "unknown";
}
}
// ==================================================================
// APIs
// ==================================================================
/*
* Enumerate all services.
*/
PyObject *
psutil_winservice_enumerate(PyObject *self, PyObject *args) {
ENUM_SERVICE_STATUS_PROCESSW *lpService = NULL;
BOOL ok;
SC_HANDLE sc = NULL;
DWORD bytesNeeded = 0;
DWORD srvCount;
DWORD resumeHandle = 0;
DWORD dwBytes = 0;
DWORD i;
PyObject *py_retlist = PyList_New(0);
PyObject *py_tuple = NULL;
PyObject *py_name = NULL;
PyObject *py_display_name = NULL;
if (py_retlist == NULL)
return NULL;
sc = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
if (sc == NULL) {
PyErr_SetFromWindowsErr(0);
return NULL;
}
for (;;) {
ok = EnumServicesStatusExW(
sc,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32, // XXX - extend this to include drivers etc.?
SERVICE_STATE_ALL,
(LPBYTE)lpService,
dwBytes,
&bytesNeeded,
&srvCount,
&resumeHandle,
NULL);
if (ok || (GetLastError() != ERROR_MORE_DATA))
break;
if (lpService)
free(lpService);
dwBytes = bytesNeeded;
lpService = (ENUM_SERVICE_STATUS_PROCESSW*)malloc(dwBytes);
}
for (i = 0; i < srvCount; i++) {
// Get unicode name / display name.
py_name = NULL;
py_name = PyUnicode_FromWideChar(
lpService[i].lpServiceName, wcslen(lpService[i].lpServiceName));
if (py_name == NULL)
goto error;
py_display_name = NULL;
py_display_name = PyUnicode_FromWideChar(
lpService[i].lpDisplayName, wcslen(lpService[i].lpDisplayName));
if (py_display_name == NULL)
goto error;
// Construct the result.
py_tuple = Py_BuildValue("(OO)", py_name, py_display_name);
if (py_tuple == NULL)
goto error;
if (PyList_Append(py_retlist, py_tuple))
goto error;
Py_DECREF(py_display_name);
Py_DECREF(py_name);
Py_DECREF(py_tuple);
}
// Free resources.
CloseServiceHandle(sc);
free(lpService);
return py_retlist;
error:
Py_DECREF(py_name);
Py_XDECREF(py_display_name);
Py_XDECREF(py_tuple);
Py_DECREF(py_retlist);
if (sc != NULL)
CloseServiceHandle(sc);
if (lpService != NULL)
free(lpService);
return NULL;
}
/*
* Get service config information. Returns:
* - display_name
* - binpath
* - username
* - startup_type
*/
PyObject *
psutil_winservice_query_config(PyObject *self, PyObject *args) {
char *service_name;
SC_HANDLE hService = NULL;
BOOL ok;
DWORD bytesNeeded = 0;
DWORD resumeHandle = 0;
DWORD dwBytes = 0;
QUERY_SERVICE_CONFIGW *qsc = NULL;
PyObject *py_tuple = NULL;
PyObject *py_unicode_display_name = NULL;
PyObject *py_unicode_binpath = NULL;
PyObject *py_unicode_username = NULL;
if (!PyArg_ParseTuple(args, "s", &service_name))
return NULL;
hService = psutil_get_service_handler(
service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_CONFIG);
if (hService == NULL)
goto error;
// First call to QueryServiceConfigW() is necessary to get the
// right size.
bytesNeeded = 0;
QueryServiceConfigW(hService, NULL, 0, &bytesNeeded);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
PyErr_SetFromWindowsErr(0);
goto error;
}
qsc = (QUERY_SERVICE_CONFIGW *)malloc(bytesNeeded);
ok = QueryServiceConfigW(hService, qsc, bytesNeeded, &bytesNeeded);
if (ok == 0) {
PyErr_SetFromWindowsErr(0);
goto error;
}
// Get unicode display name.
py_unicode_display_name = PyUnicode_FromWideChar(
qsc->lpDisplayName, wcslen(qsc->lpDisplayName));
if (py_unicode_display_name == NULL)
goto error;
// Get unicode bin path.
py_unicode_binpath = PyUnicode_FromWideChar(
qsc->lpBinaryPathName, wcslen(qsc->lpBinaryPathName));
if (py_unicode_binpath == NULL)
goto error;
// Get unicode username.
py_unicode_username = PyUnicode_FromWideChar(
qsc->lpServiceStartName, wcslen(qsc->lpServiceStartName));
if (py_unicode_username == NULL)
goto error;
// Construct result tuple.
py_tuple = Py_BuildValue(
"(OOOs)",
py_unicode_display_name,
py_unicode_binpath,
py_unicode_username,
get_startup_string(qsc->dwStartType) // startup
);
if (py_tuple == NULL)
goto error;
// Free resources.
Py_DECREF(py_unicode_display_name);
Py_DECREF(py_unicode_binpath);
Py_DECREF(py_unicode_username);
free(qsc);
CloseServiceHandle(hService);
return py_tuple;
error:
Py_XDECREF(py_unicode_display_name);
Py_XDECREF(py_unicode_binpath);
Py_XDECREF(py_unicode_username);
Py_XDECREF(py_tuple);
if (hService != NULL)
CloseServiceHandle(hService);
if (qsc != NULL)
free(qsc);
return NULL;
}
/*
* Get service status information. Returns:
* - status
* - pid
*/
PyObject *
psutil_winservice_query_status(PyObject *self, PyObject *args) {
char *service_name;
SC_HANDLE hService = NULL;
BOOL ok;
DWORD bytesNeeded = 0;
DWORD resumeHandle = 0;
DWORD dwBytes = 0;
SERVICE_STATUS_PROCESS *ssp = NULL;
PyObject *py_tuple = NULL;
if (!PyArg_ParseTuple(args, "s", &service_name))
return NULL;
hService = psutil_get_service_handler(
service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_STATUS);
if (hService == NULL)
goto error;
// First call to QueryServiceStatusEx() is necessary to get the
// right size.
QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, NULL, 0,
&bytesNeeded);
if (GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
// Also services.msc fails in the same manner, so we return an
// empty string.
CloseServiceHandle(hService);
return Py_BuildValue("s", "");
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
PyErr_SetFromWindowsErr(0);
goto error;
}
ssp = (SERVICE_STATUS_PROCESS *)HeapAlloc(
GetProcessHeap(), 0, bytesNeeded);
if (ssp == NULL) {
PyErr_NoMemory();
goto error;
}
// Actual call.
ok = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)ssp,
bytesNeeded, &bytesNeeded);
if (ok == 0) {
PyErr_SetFromWindowsErr(0);
goto error;
}
py_tuple = Py_BuildValue(
"(sk)",
get_state_string(ssp->dwCurrentState),
ssp->dwProcessId
);
if (py_tuple == NULL)
goto error;
CloseServiceHandle(hService);
HeapFree(GetProcessHeap(), 0, ssp);
return py_tuple;
error:
Py_XDECREF(py_tuple);
if (hService != NULL)
CloseServiceHandle(hService);
if (ssp != NULL)
HeapFree(GetProcessHeap(), 0, ssp);
return NULL;
}
/*
* Get service description.
*/
PyObject *
psutil_winservice_query_descr(PyObject *self, PyObject *args) {
ENUM_SERVICE_STATUS_PROCESSW *lpService = NULL;
BOOL ok;
DWORD bytesNeeded = 0;
DWORD resumeHandle = 0;
DWORD dwBytes = 0;
SC_HANDLE hService = NULL;
SERVICE_DESCRIPTIONW *scd = NULL;
char *service_name;
PyObject *py_retstr = NULL;
if (!PyArg_ParseTuple(args, "s", &service_name))
return NULL;
hService = psutil_get_service_handler(
service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_CONFIG);
if (hService == NULL)
goto error;
// This first call to QueryServiceConfig2W() is necessary in order
// to get the right size.
bytesNeeded = 0;
QueryServiceConfig2W(hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0,
&bytesNeeded);
if (GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
// Also services.msc fails in the same manner, so we return an
// empty string.
CloseServiceHandle(hService);
return Py_BuildValue("s", "");
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
PyErr_SetFromWindowsErr(0);
goto error;
}
scd = (SERVICE_DESCRIPTIONW *)malloc(bytesNeeded);
ok = QueryServiceConfig2W(hService, SERVICE_CONFIG_DESCRIPTION,
(LPBYTE)scd, bytesNeeded, &bytesNeeded);
if (ok == 0) {
PyErr_SetFromWindowsErr(0);
goto error;
}
if (scd->lpDescription == NULL) {
py_retstr = Py_BuildValue("s", "");
}
else {
py_retstr = PyUnicode_FromWideChar(
scd->lpDescription, wcslen(scd->lpDescription));
}
if (!py_retstr)
goto error;
free(scd);
CloseServiceHandle(hService);
return py_retstr;
error:
if (hService != NULL)
CloseServiceHandle(hService);
if (lpService != NULL)
free(lpService);
return NULL;
}
/*
* Start service.
* XXX - note: this is exposed but not used.
*/
PyObject *
psutil_winservice_start(PyObject *self, PyObject *args) {
char *service_name;
BOOL ok;
SC_HANDLE hService = NULL;
if (!PyArg_ParseTuple(args, "s", &service_name))
return NULL;
hService = psutil_get_service_handler(
service_name, SC_MANAGER_ALL_ACCESS, SERVICE_START);
if (hService == NULL) {
goto error;
}
ok = StartService(hService, 0, NULL);
if (ok == 0) {
PyErr_SetFromWindowsErr(0);
goto error;
}
Py_RETURN_NONE;
error:
if (hService != NULL)
CloseServiceHandle(hService);
return NULL;
}
/*
* Stop service.
* XXX - note: this is exposed but not used.
*/
PyObject *
psutil_winservice_stop(PyObject *self, PyObject *args) {
char *service_name;
BOOL ok;
SC_HANDLE hService = NULL;
SERVICE_STATUS ssp;
if (!PyArg_ParseTuple(args, "s", &service_name))
return NULL;
hService = psutil_get_service_handler(
service_name, SC_MANAGER_ALL_ACCESS, SERVICE_STOP);
if (hService == NULL)
goto error;
// Note: this can hang for 30 secs.
Py_BEGIN_ALLOW_THREADS
ok = ControlService(hService, SERVICE_CONTROL_STOP, &ssp);
Py_END_ALLOW_THREADS
if (ok == 0) {
PyErr_SetFromWindowsErr(0);
goto error;
}
CloseServiceHandle(hService);
Py_RETURN_NONE;
error:
if (hService != NULL)
CloseServiceHandle(hService);
return NULL;
}

17
third_party/python/psutil/psutil/arch/windows/services.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <Python.h>
#include <Winsvc.h>
SC_HANDLE psutil_get_service_handle(
char service_name, DWORD scm_access, DWORD access);
PyObject *psutil_winservice_enumerate(PyObject *self, PyObject *args);
PyObject *psutil_winservice_query_config(PyObject *self, PyObject *args);
PyObject *psutil_winservice_query_status(PyObject *self, PyObject *args);
PyObject *psutil_winservice_query_descr(PyObject *self, PyObject *args);
PyObject *psutil_winservice_start(PyObject *self, PyObject *args);
PyObject *psutil_winservice_stop(PyObject *self, PyObject *args);

23
third_party/python/psutil/psutil/tests/README.rst поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
Instructions for running tests
==============================
* There are two ways of running tests. As a "user", if psutil is already
installed and you just want to test it works::
python -m psutil.tests --install-deps # install test deps
python -m psutil.tests
As a "developer", if you have a copy of the source code and you whish to hack
on psutil::
make setup-dev-env # install test deps (+ other things)
make test
* To run tests on all supported Python versions install tox
(``pip install tox``) then run ``tox`` from within psutil root directory.
* Every time a commit is pushed tests are automatically run on Travis
(Linux, OSX) and appveyor (Windows):
* Travis builds: https://travis-ci.org/giampaolo/psutil
* AppVeyor builds: https://ci.appveyor.com/project/giampaolo/psutil

1198
third_party/python/psutil/psutil/tests/__init__.py поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

96
third_party/python/psutil/psutil/tests/__main__.py поставляемый Normal file
Просмотреть файл

@ -0,0 +1,96 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Run unit tests. This is invoked by:
$ python -m psutil.tests
"""
import contextlib
import optparse
import os
import ssl
import sys
import tempfile
try:
from urllib.request import urlopen # py3
except ImportError:
from urllib2 import urlopen
from psutil.tests import PYTHON_EXE
from psutil.tests import run_suite
HERE = os.path.abspath(os.path.dirname(__file__))
GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
TEST_DEPS = []
if sys.version_info[:2] == (2, 6):
TEST_DEPS.extend(["ipaddress", "unittest2", "argparse", "mock==1.0.1"])
elif sys.version_info[:2] == (2, 7) or sys.version_info[:2] <= (3, 2):
TEST_DEPS.extend(["ipaddress", "mock"])
elif sys.version_info[:2] == (3, 3):
TEST_DEPS.extend(["ipaddress"])
def install_pip():
try:
import pip # NOQA
except ImportError:
f = tempfile.NamedTemporaryFile(suffix='.py')
with contextlib.closing(f):
print("downloading %s to %s" % (GET_PIP_URL, f.name))
if hasattr(ssl, '_create_unverified_context'):
ctx = ssl._create_unverified_context()
else:
ctx = None
kwargs = dict(context=ctx) if ctx else {}
req = urlopen(GET_PIP_URL, **kwargs)
data = req.read()
f.write(data)
f.flush()
print("installing pip")
code = os.system('%s %s --user' % (PYTHON_EXE, f.name))
return code
def install_test_deps(deps=None):
"""Install test dependencies via pip."""
if deps is None:
deps = TEST_DEPS
deps = set(deps)
if deps:
is_venv = hasattr(sys, 'real_prefix')
opts = "--user" if not is_venv else ""
install_pip()
code = os.system('%s -m pip install %s --upgrade %s' % (
PYTHON_EXE, opts, " ".join(deps)))
return code
def main():
usage = "%s -m psutil.tests [opts]" % PYTHON_EXE
parser = optparse.OptionParser(usage=usage, description="run unit tests")
parser.add_option("-i", "--install-deps",
action="store_true", default=False,
help="don't print status messages to stdout")
opts, args = parser.parse_args()
if opts.install_deps:
install_pip()
install_test_deps()
else:
for dep in TEST_DEPS:
try:
__import__(dep.split("==")[0])
except ImportError:
sys.exit("%r lib is not installed; run %s -m psutil.tests "
"--install-deps" % (dep, PYTHON_EXE))
run_suite()
main()

489
third_party/python/psutil/psutil/tests/test_bsd.py поставляемый Normal file
Просмотреть файл

@ -0,0 +1,489 @@
#!/usr/bin/env python
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# TODO: (FreeBSD) add test for comparing connections with 'sockstat' cmd.
"""Tests specific to all BSD platforms."""
import datetime
import os
import re
import time
import psutil
from psutil import BSD
from psutil import FREEBSD
from psutil import NETBSD
from psutil import OPENBSD
from psutil.tests import get_test_subprocess
from psutil.tests import HAS_BATTERY
from psutil.tests import MEMORY_TOLERANCE
from psutil.tests import reap_children
from psutil.tests import retry_before_failing
from psutil.tests import run_test_module_by_name
from psutil.tests import sh
from psutil.tests import unittest
from psutil.tests import which
if BSD:
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
if os.getuid() == 0: # muse requires root privileges
MUSE_AVAILABLE = which('muse')
else:
MUSE_AVAILABLE = False
else:
MUSE_AVAILABLE = False
def sysctl(cmdline):
"""Expects a sysctl command with an argument and parse the result
returning only the value of interest.
"""
result = sh("sysctl " + cmdline)
if FREEBSD:
result = result[result.find(": ") + 2:]
elif OPENBSD or NETBSD:
result = result[result.find("=") + 1:]
try:
return int(result)
except ValueError:
return result
def muse(field):
"""Thin wrapper around 'muse' cmdline utility."""
out = sh('muse')
for line in out.split('\n'):
if line.startswith(field):
break
else:
raise ValueError("line not found")
return int(line.split()[1])
# =====================================================================
# --- All BSD*
# =====================================================================
@unittest.skipIf(not BSD, "BSD only")
class BSDSpecificTestCase(unittest.TestCase):
"""Generic tests common to all BSD variants."""
@classmethod
def setUpClass(cls):
cls.pid = get_test_subprocess().pid
@classmethod
def tearDownClass(cls):
reap_children()
@unittest.skipIf(NETBSD, "-o lstart doesn't work on NETBSD")
def test_process_create_time(self):
output = sh("ps -o lstart -p %s" % self.pid)
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))
@unittest.skipIf(not which('sysctl'), "sysctl cmd not available")
def test_cpu_count_logical(self):
syst = sysctl("hw.ncpu")
self.assertEqual(psutil.cpu_count(logical=True), syst)
@unittest.skipIf(not which('sysctl'), "sysctl cmd not available")
def test_virtual_memory_total(self):
num = sysctl('hw.physmem')
self.assertEqual(num, psutil.virtual_memory().total)
def test_net_if_stats(self):
for name, stats in psutil.net_if_stats().items():
try:
out = sh("ifconfig %s" % name)
except RuntimeError:
pass
else:
self.assertEqual(stats.isup, 'RUNNING' in out, msg=out)
if "mtu" in out:
self.assertEqual(stats.mtu,
int(re.findall(r'mtu (\d+)', out)[0]))
# =====================================================================
# --- FreeBSD
# =====================================================================
@unittest.skipIf(not FREEBSD, "FREEBSD only")
class FreeBSDSpecificTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.pid = get_test_subprocess().pid
@classmethod
def tearDownClass(cls):
reap_children()
@retry_before_failing()
def test_proc_memory_maps(self):
out = sh('procstat -v %s' % self.pid)
maps = psutil.Process(self.pid).memory_maps(grouped=False)
lines = out.split('\n')[1:]
while lines:
line = lines.pop()
fields = line.split()
_, start, stop, perms, res = fields[:5]
map = maps.pop()
self.assertEqual("%s-%s" % (start, stop), map.addr)
self.assertEqual(int(res), map.rss)
if not map.path.startswith('['):
self.assertEqual(fields[10], map.path)
def test_proc_exe(self):
out = sh('procstat -b %s' % self.pid)
self.assertEqual(psutil.Process(self.pid).exe(),
out.split('\n')[1].split()[-1])
def test_proc_cmdline(self):
out = sh('procstat -c %s' % self.pid)
self.assertEqual(' '.join(psutil.Process(self.pid).cmdline()),
' '.join(out.split('\n')[1].split()[2:]))
def test_proc_uids_gids(self):
out = sh('procstat -s %s' % self.pid)
euid, ruid, suid, egid, rgid, sgid = out.split('\n')[1].split()[2:8]
p = psutil.Process(self.pid)
uids = p.uids()
gids = p.gids()
self.assertEqual(uids.real, int(ruid))
self.assertEqual(uids.effective, int(euid))
self.assertEqual(uids.saved, int(suid))
self.assertEqual(gids.real, int(rgid))
self.assertEqual(gids.effective, int(egid))
self.assertEqual(gids.saved, int(sgid))
@retry_before_failing()
def test_proc_ctx_switches(self):
tested = []
out = sh('procstat -r %s' % self.pid)
p = psutil.Process(self.pid)
for line in out.split('\n'):
line = line.lower().strip()
if ' voluntary context' in line:
pstat_value = int(line.split()[-1])
psutil_value = p.num_ctx_switches().voluntary
self.assertEqual(pstat_value, psutil_value)
tested.append(None)
elif ' involuntary context' in line:
pstat_value = int(line.split()[-1])
psutil_value = p.num_ctx_switches().involuntary
self.assertEqual(pstat_value, psutil_value)
tested.append(None)
if len(tested) != 2:
raise RuntimeError("couldn't find lines match in procstat out")
@retry_before_failing()
def test_proc_cpu_times(self):
tested = []
out = sh('procstat -r %s' % self.pid)
p = psutil.Process(self.pid)
for line in out.split('\n'):
line = line.lower().strip()
if 'user time' in line:
pstat_value = float('0.' + line.split()[-1].split('.')[-1])
psutil_value = p.cpu_times().user
self.assertEqual(pstat_value, psutil_value)
tested.append(None)
elif 'system time' in line:
pstat_value = float('0.' + line.split()[-1].split('.')[-1])
psutil_value = p.cpu_times().system
self.assertEqual(pstat_value, psutil_value)
tested.append(None)
if len(tested) != 2:
raise RuntimeError("couldn't find lines match in procstat out")
# --- virtual_memory(); tests against sysctl
@retry_before_failing()
def test_vmem_active(self):
syst = sysctl("vm.stats.vm.v_active_count") * PAGESIZE
self.assertAlmostEqual(psutil.virtual_memory().active, syst,
delta=MEMORY_TOLERANCE)
@retry_before_failing()
def test_vmem_inactive(self):
syst = sysctl("vm.stats.vm.v_inactive_count") * PAGESIZE
self.assertAlmostEqual(psutil.virtual_memory().inactive, syst,
delta=MEMORY_TOLERANCE)
@retry_before_failing()
def test_vmem_wired(self):
syst = sysctl("vm.stats.vm.v_wire_count") * PAGESIZE
self.assertAlmostEqual(psutil.virtual_memory().wired, syst,
delta=MEMORY_TOLERANCE)
@retry_before_failing()
def test_vmem_cached(self):
syst = sysctl("vm.stats.vm.v_cache_count") * PAGESIZE
self.assertAlmostEqual(psutil.virtual_memory().cached, syst,
delta=MEMORY_TOLERANCE)
@retry_before_failing()
def test_vmem_free(self):
syst = sysctl("vm.stats.vm.v_free_count") * PAGESIZE
self.assertAlmostEqual(psutil.virtual_memory().free, syst,
delta=MEMORY_TOLERANCE)
@retry_before_failing()
def test_vmem_buffers(self):
syst = sysctl("vfs.bufspace")
self.assertAlmostEqual(psutil.virtual_memory().buffers, syst,
delta=MEMORY_TOLERANCE)
# --- virtual_memory(); tests against muse
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
def test_muse_vmem_total(self):
num = muse('Total')
self.assertEqual(psutil.virtual_memory().total, num)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_active(self):
num = muse('Active')
self.assertAlmostEqual(psutil.virtual_memory().active, num,
delta=MEMORY_TOLERANCE)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_inactive(self):
num = muse('Inactive')
self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
delta=MEMORY_TOLERANCE)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_wired(self):
num = muse('Wired')
self.assertAlmostEqual(psutil.virtual_memory().wired, num,
delta=MEMORY_TOLERANCE)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_cached(self):
num = muse('Cache')
self.assertAlmostEqual(psutil.virtual_memory().cached, num,
delta=MEMORY_TOLERANCE)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_free(self):
num = muse('Free')
self.assertAlmostEqual(psutil.virtual_memory().free, num,
delta=MEMORY_TOLERANCE)
@unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
@retry_before_failing()
def test_muse_vmem_buffers(self):
num = muse('Buffer')
self.assertAlmostEqual(psutil.virtual_memory().buffers, num,
delta=MEMORY_TOLERANCE)
def test_cpu_stats_ctx_switches(self):
self.assertAlmostEqual(psutil.cpu_stats().ctx_switches,
sysctl('vm.stats.sys.v_swtch'), delta=1000)
def test_cpu_stats_interrupts(self):
self.assertAlmostEqual(psutil.cpu_stats().interrupts,
sysctl('vm.stats.sys.v_intr'), delta=1000)
def test_cpu_stats_soft_interrupts(self):
self.assertAlmostEqual(psutil.cpu_stats().soft_interrupts,
sysctl('vm.stats.sys.v_soft'), delta=1000)
def test_cpu_stats_syscalls(self):
self.assertAlmostEqual(psutil.cpu_stats().syscalls,
sysctl('vm.stats.sys.v_syscall'), delta=1000)
# def test_cpu_stats_traps(self):
# self.assertAlmostEqual(psutil.cpu_stats().traps,
# sysctl('vm.stats.sys.v_trap'), delta=1000)
# --- others
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())
# --- sensors_battery
@unittest.skipIf(not HAS_BATTERY, "no battery")
def test_sensors_battery(self):
def secs2hours(secs):
m, s = divmod(secs, 60)
h, m = divmod(m, 60)
return "%d:%02d" % (h, m)
out = sh("acpiconf -i 0")
fields = dict([(x.split('\t')[0], x.split('\t')[-1])
for x in out.split("\n")])
metrics = psutil.sensors_battery()
percent = int(fields['Remaining capacity:'].replace('%', ''))
remaining_time = fields['Remaining time:']
self.assertEqual(metrics.percent, percent)
if remaining_time == 'unknown':
self.assertEqual(metrics.secsleft, psutil.POWER_TIME_UNLIMITED)
else:
self.assertEqual(secs2hours(metrics.secsleft), remaining_time)
@unittest.skipIf(not HAS_BATTERY, "no battery")
def test_sensors_battery_against_sysctl(self):
self.assertEqual(psutil.sensors_battery().percent,
sysctl("hw.acpi.battery.life"))
self.assertEqual(psutil.sensors_battery().power_plugged,
sysctl("hw.acpi.acline") == 1)
secsleft = psutil.sensors_battery().secsleft
if secsleft < 0:
self.assertEqual(sysctl("hw.acpi.battery.time"), -1)
else:
self.assertEqual(secsleft, sysctl("hw.acpi.battery.time") * 60)
@unittest.skipIf(HAS_BATTERY, "has battery")
def test_sensors_battery_no_battery(self):
# If no battery is present one of these calls is supposed
# to fail, see:
# https://github.com/giampaolo/psutil/issues/1074
with self.assertRaises(RuntimeError):
sysctl("hw.acpi.battery.life")
sysctl("hw.acpi.battery.time")
sysctl("hw.acpi.acline")
self.assertIsNone(psutil.sensors_battery())
# =====================================================================
# --- OpenBSD
# =====================================================================
@unittest.skipIf(not OPENBSD, "OPENBSD only")
class OpenBSDSpecificTestCase(unittest.TestCase):
def test_boot_time(self):
s = sysctl('kern.boottime')
sys_bt = datetime.datetime.strptime(s, "%a %b %d %H:%M:%S %Y")
psutil_bt = datetime.datetime.fromtimestamp(psutil.boot_time())
self.assertEqual(sys_bt, psutil_bt)
# =====================================================================
# --- NetBSD
# =====================================================================
@unittest.skipIf(not NETBSD, "NETBSD only")
class NetBSDSpecificTestCase(unittest.TestCase):
@staticmethod
def parse_meminfo(look_for):
with open('/proc/meminfo', 'rb') as f:
for line in f:
if line.startswith(look_for):
return int(line.split()[1]) * 1024
raise ValueError("can't find %s" % look_for)
def test_vmem_total(self):
self.assertEqual(
psutil.virtual_memory().total, self.parse_meminfo("MemTotal:"))
def test_vmem_free(self):
self.assertAlmostEqual(
psutil.virtual_memory().free, self.parse_meminfo("MemFree:"),
delta=MEMORY_TOLERANCE)
def test_vmem_buffers(self):
self.assertAlmostEqual(
psutil.virtual_memory().buffers, self.parse_meminfo("Buffers:"),
delta=MEMORY_TOLERANCE)
def test_vmem_shared(self):
self.assertAlmostEqual(
psutil.virtual_memory().shared, self.parse_meminfo("MemShared:"),
delta=MEMORY_TOLERANCE)
def test_swapmem_total(self):
self.assertAlmostEqual(
psutil.swap_memory().total, self.parse_meminfo("SwapTotal:"),
delta=MEMORY_TOLERANCE)
def test_swapmem_free(self):
self.assertAlmostEqual(
psutil.swap_memory().free, self.parse_meminfo("SwapFree:"),
delta=MEMORY_TOLERANCE)
def test_swapmem_used(self):
smem = psutil.swap_memory()
self.assertEqual(smem.used, smem.total - smem.free)
def test_cpu_stats_interrupts(self):
with open('/proc/stat', 'rb') as f:
for line in f:
if line.startswith(b'intr'):
interrupts = int(line.split()[1])
break
else:
raise ValueError("couldn't find line")
self.assertAlmostEqual(
psutil.cpu_stats().interrupts, interrupts, delta=1000)
def test_cpu_stats_ctx_switches(self):
with open('/proc/stat', 'rb') as f:
for line in f:
if line.startswith(b'ctxt'):
ctx_switches = int(line.split()[1])
break
else:
raise ValueError("couldn't find line")
self.assertAlmostEqual(
psutil.cpu_stats().ctx_switches, ctx_switches, delta=1000)
if __name__ == '__main__':
run_test_module_by_name(__file__)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше